├── .gitignore ├── LICENSE ├── README.md ├── nodejs ├── app.js ├── appsInfo.js ├── bin │ └── www ├── node_modules │ ├── body-parser │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── read.js │ │ │ └── types │ │ │ │ ├── json.js │ │ │ │ ├── raw.js │ │ │ │ ├── text.js │ │ │ │ └── urlencoded.js │ │ └── package.json │ ├── cookie-parser │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── node_modules │ │ │ └── cookie │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ └── package.json │ ├── debug │ │ ├── .npmignore │ │ ├── Makefile │ │ ├── Readme.md │ │ ├── component.json │ │ ├── node.js │ │ └── package.json │ ├── express │ │ ├── History.md │ │ ├── LICENSE │ │ ├── Readme.md │ │ ├── index.js │ │ ├── lib │ │ │ ├── application.js │ │ │ ├── express.js │ │ │ ├── middleware │ │ │ │ ├── init.js │ │ │ │ └── query.js │ │ │ ├── request.js │ │ │ ├── response.js │ │ │ ├── router │ │ │ │ ├── index.js │ │ │ │ ├── layer.js │ │ │ │ └── route.js │ │ │ ├── utils.js │ │ │ └── view.js │ │ └── package.json │ ├── jssha │ │ ├── CHANGELOG │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ ├── package.json │ │ └── src │ │ │ └── sha.js │ └── morgan │ │ ├── HISTORY.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ └── package.json ├── package.json ├── public │ └── stylesheets │ │ └── style.css ├── routes │ ├── index.js │ └── wechat.js ├── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── yarn.lock └── web ├── css └── index.css ├── index.html └── js └── jquery.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | jsconfig.json 23 | *.code-workspace 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 sheldon.wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 经常忘掉服务端示例的下载地址,这里注释一下 2 | 3 | https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html 4 | 5 | [签名算法各语言版本下载](https://res.wx.qq.com/op_res/-serEQ6xSDVIjfoOHcX78T1JAYX-pM_fghzfiNYoD8uHVd3fOeC0PC_pvlg4-kmP) 6 | 7 | 8 | # wechat-JS-SDK-demo (更新时间: 2020-10-30) 9 | 成功演示地址,使用 *微信* 或 *微信开发者工具* 访问 10 | 11 | https://tiepili.com/web/index.html 12 | 13 | 分享时会显示 ok 的信息,分享的图引用的是百度的logo 14 | 15 | ##### 此项目用于测试新版微信JS-SDK的分享API 16 | ###### *注意:一定要花钱 分享API的调用需要确保您的appid是否通过了微信的官方认证,这一点是关键,否则无法成功调用分享API* 17 | 18 | 19 | 20 | ##### 添加 ip 白名单 21 | 位置:公众号->开发->基本配置->IP白名单 22 | 23 | 添加你自己服务器域名对就的IP地址 24 | 25 | 如果获取微信公众号授权失败, 请稍后重试! 公众平台返回原始数据为: 错误代码-40164,错误信息-invalid ip, not in whitelist hint: [59FKqA0797e514] 26 | 27 | ##### 添加 业务域名、JS接口安全域名、网页授权域名 28 | 位置:公众号->设置->公众号设置->功能设置 29 | 30 | 此处添加自己的域名,比如 tiepili.com (填了顶级域名后二级域名就不用填了) 31 | 32 | 33 | ##### 项目运行中可能出现的错误 34 | - 如果你分了两个环境两个域名使用的是同一个 appid 则有可能在访问其中一个域名签名成功后,另一个域名再访问时,签名失败,因为服务端有可能会缓存7200秒的token 35 | - 出错后记得清一下缓存,因为缓存中可能存的是错误的签名 36 | 37 | ### 文件夹说明 38 | 39 | ##### nodejs文件夹下为服务端 40 | - 微信数字签名只能由服务器端生成 41 | - 这里数字签名生成示例用于放在 NodeJS 服务器环境下,用于产生微信 JS-SDK 的数字签名服务 42 | 43 | ##### nodejs/appsInfo.js 为微信appid及secret的配置文件 44 | ##### nodejs/routes/wechat.js 为签名生成服务逻辑 45 | 46 | 47 | ##### 如果要测试 nodejs 服务端运行说明 48 | - yarn v1.17.3 49 | - node v12.16.3 50 | - 需要将 appsInfo.js 内的 appid 和 secret 换成自己的然 51 | 52 | 53 | 54 | 55 | ### client-web文件夹下为浏览器端普通WEB页 56 | client-web 下是静态html项目,会请求 nodejs 下运行的数字签名服务,用于测试微信分享API及其它 57 | 58 | 注意:服务端可以换成任意其它语言,为演示方便我使用了 NodeJS 版 59 | 60 | 61 | [更多介绍](http://www.cnblogs.com/willian/p/4254963.html) 62 | 63 | -------------------------------------------------------------------------------- /nodejs/app.js: -------------------------------------------------------------------------------- 1 | var createError = require('http-errors'); 2 | var express = require('express'); 3 | var path = require('path'); 4 | var cookieParser = require('cookie-parser'); 5 | var logger = require('morgan'); 6 | 7 | var indexRouter = require('./routes/index'); 8 | var wechatRouter = require('./routes/wechat'); 9 | 10 | var app = express(); 11 | 12 | // view engine setup 13 | app.set('views', path.join(__dirname, 'views')); 14 | app.set('view engine', 'jade'); 15 | 16 | app.use(logger('dev')); 17 | app.use(express.json()); 18 | app.use(express.urlencoded({ extended: false })); 19 | app.use(cookieParser()); 20 | app.use(express.static(path.join(__dirname, 'public'))); 21 | 22 | app.use('/', indexRouter); 23 | app.use('/wechat', wechatRouter); 24 | 25 | // catch 404 and forward to error handler 26 | app.use(function(req, res, next) { 27 | next(createError(404)); 28 | }); 29 | 30 | // error handler 31 | app.use(function(err, req, res, next) { 32 | // set locals, only providing error in development 33 | res.locals.message = err.message; 34 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 35 | 36 | // render the error page 37 | res.status(err.status || 500); 38 | res.render('error'); 39 | }); 40 | 41 | module.exports = app; 42 | -------------------------------------------------------------------------------- /nodejs/appsInfo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 微信认证后的 app 信息 3 | * 如果有需要可以将这些信息放到数据库中读取方便以更增加 4 | * 注:测试时请替换您真实的appid和secret 5 | */ 6 | module.exports = function(){ 7 | return [ 8 | { 9 | appid: 'wxa0f06601f194xxxx', 10 | secret: '097fd14bac218d0fb016d02f525dxxxx' 11 | } 12 | ]; 13 | }; 14 | -------------------------------------------------------------------------------- /nodejs/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('nodejs:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/HISTORY.md: -------------------------------------------------------------------------------- 1 | 1.18.3 / 2018-05-14 2 | =================== 3 | 4 | * Fix stack trace for strict json parse error 5 | * deps: depd@~1.1.2 6 | - perf: remove argument reassignment 7 | * deps: http-errors@~1.6.3 8 | - deps: depd@~1.1.2 9 | - deps: setprototypeof@1.1.0 10 | - deps: statuses@'>= 1.3.1 < 2' 11 | * deps: iconv-lite@0.4.23 12 | - Fix loading encoding with year appended 13 | - Fix deprecation warnings on Node.js 10+ 14 | * deps: qs@6.5.2 15 | * deps: raw-body@2.3.3 16 | - deps: http-errors@1.6.3 17 | - deps: iconv-lite@0.4.23 18 | * deps: type-is@~1.6.16 19 | - deps: mime-types@~2.1.18 20 | 21 | 1.18.2 / 2017-09-22 22 | =================== 23 | 24 | * deps: debug@2.6.9 25 | * perf: remove argument reassignment 26 | 27 | 1.18.1 / 2017-09-12 28 | =================== 29 | 30 | * deps: content-type@~1.0.4 31 | - perf: remove argument reassignment 32 | - perf: skip parameter parsing when no parameters 33 | * deps: iconv-lite@0.4.19 34 | - Fix ISO-8859-1 regression 35 | - Update Windows-1255 36 | * deps: qs@6.5.1 37 | - Fix parsing & compacting very deep objects 38 | * deps: raw-body@2.3.2 39 | - deps: iconv-lite@0.4.19 40 | 41 | 1.18.0 / 2017-09-08 42 | =================== 43 | 44 | * Fix JSON strict violation error to match native parse error 45 | * Include the `body` property on verify errors 46 | * Include the `type` property on all generated errors 47 | * Use `http-errors` to set status code on errors 48 | * deps: bytes@3.0.0 49 | * deps: debug@2.6.8 50 | * deps: depd@~1.1.1 51 | - Remove unnecessary `Buffer` loading 52 | * deps: http-errors@~1.6.2 53 | - deps: depd@1.1.1 54 | * deps: iconv-lite@0.4.18 55 | - Add support for React Native 56 | - Add a warning if not loaded as utf-8 57 | - Fix CESU-8 decoding in Node.js 8 58 | - Improve speed of ISO-8859-1 encoding 59 | * deps: qs@6.5.0 60 | * deps: raw-body@2.3.1 61 | - Use `http-errors` for standard emitted errors 62 | - deps: bytes@3.0.0 63 | - deps: iconv-lite@0.4.18 64 | - perf: skip buffer decoding on overage chunk 65 | * perf: prevent internal `throw` when missing charset 66 | 67 | 1.17.2 / 2017-05-17 68 | =================== 69 | 70 | * deps: debug@2.6.7 71 | - Fix `DEBUG_MAX_ARRAY_LENGTH` 72 | - deps: ms@2.0.0 73 | * deps: type-is@~1.6.15 74 | - deps: mime-types@~2.1.15 75 | 76 | 1.17.1 / 2017-03-06 77 | =================== 78 | 79 | * deps: qs@6.4.0 80 | - Fix regression parsing keys starting with `[` 81 | 82 | 1.17.0 / 2017-03-01 83 | =================== 84 | 85 | * deps: http-errors@~1.6.1 86 | - Make `message` property enumerable for `HttpError`s 87 | - deps: setprototypeof@1.0.3 88 | * deps: qs@6.3.1 89 | - Fix compacting nested arrays 90 | 91 | 1.16.1 / 2017-02-10 92 | =================== 93 | 94 | * deps: debug@2.6.1 95 | - Fix deprecation messages in WebStorm and other editors 96 | - Undeprecate `DEBUG_FD` set to `1` or `2` 97 | 98 | 1.16.0 / 2017-01-17 99 | =================== 100 | 101 | * deps: debug@2.6.0 102 | - Allow colors in workers 103 | - Deprecated `DEBUG_FD` environment variable 104 | - Fix error when running under React Native 105 | - Use same color for same namespace 106 | - deps: ms@0.7.2 107 | * deps: http-errors@~1.5.1 108 | - deps: inherits@2.0.3 109 | - deps: setprototypeof@1.0.2 110 | - deps: statuses@'>= 1.3.1 < 2' 111 | * deps: iconv-lite@0.4.15 112 | - Added encoding MS-31J 113 | - Added encoding MS-932 114 | - Added encoding MS-936 115 | - Added encoding MS-949 116 | - Added encoding MS-950 117 | - Fix GBK/GB18030 handling of Euro character 118 | * deps: qs@6.2.1 119 | - Fix array parsing from skipping empty values 120 | * deps: raw-body@~2.2.0 121 | - deps: iconv-lite@0.4.15 122 | * deps: type-is@~1.6.14 123 | - deps: mime-types@~2.1.13 124 | 125 | 1.15.2 / 2016-06-19 126 | =================== 127 | 128 | * deps: bytes@2.4.0 129 | * deps: content-type@~1.0.2 130 | - perf: enable strict mode 131 | * deps: http-errors@~1.5.0 132 | - Use `setprototypeof` module to replace `__proto__` setting 133 | - deps: statuses@'>= 1.3.0 < 2' 134 | - perf: enable strict mode 135 | * deps: qs@6.2.0 136 | * deps: raw-body@~2.1.7 137 | - deps: bytes@2.4.0 138 | - perf: remove double-cleanup on happy path 139 | * deps: type-is@~1.6.13 140 | - deps: mime-types@~2.1.11 141 | 142 | 1.15.1 / 2016-05-05 143 | =================== 144 | 145 | * deps: bytes@2.3.0 146 | - Drop partial bytes on all parsed units 147 | - Fix parsing byte string that looks like hex 148 | * deps: raw-body@~2.1.6 149 | - deps: bytes@2.3.0 150 | * deps: type-is@~1.6.12 151 | - deps: mime-types@~2.1.10 152 | 153 | 1.15.0 / 2016-02-10 154 | =================== 155 | 156 | * deps: http-errors@~1.4.0 157 | - Add `HttpError` export, for `err instanceof createError.HttpError` 158 | - deps: inherits@2.0.1 159 | - deps: statuses@'>= 1.2.1 < 2' 160 | * deps: qs@6.1.0 161 | * deps: type-is@~1.6.11 162 | - deps: mime-types@~2.1.9 163 | 164 | 1.14.2 / 2015-12-16 165 | =================== 166 | 167 | * deps: bytes@2.2.0 168 | * deps: iconv-lite@0.4.13 169 | * deps: qs@5.2.0 170 | * deps: raw-body@~2.1.5 171 | - deps: bytes@2.2.0 172 | - deps: iconv-lite@0.4.13 173 | * deps: type-is@~1.6.10 174 | - deps: mime-types@~2.1.8 175 | 176 | 1.14.1 / 2015-09-27 177 | =================== 178 | 179 | * Fix issue where invalid charset results in 400 when `verify` used 180 | * deps: iconv-lite@0.4.12 181 | - Fix CESU-8 decoding in Node.js 4.x 182 | * deps: raw-body@~2.1.4 183 | - Fix masking critical errors from `iconv-lite` 184 | - deps: iconv-lite@0.4.12 185 | * deps: type-is@~1.6.9 186 | - deps: mime-types@~2.1.7 187 | 188 | 1.14.0 / 2015-09-16 189 | =================== 190 | 191 | * Fix JSON strict parse error to match syntax errors 192 | * Provide static `require` analysis in `urlencoded` parser 193 | * deps: depd@~1.1.0 194 | - Support web browser loading 195 | * deps: qs@5.1.0 196 | * deps: raw-body@~2.1.3 197 | - Fix sync callback when attaching data listener causes sync read 198 | * deps: type-is@~1.6.8 199 | - Fix type error when given invalid type to match against 200 | - deps: mime-types@~2.1.6 201 | 202 | 1.13.3 / 2015-07-31 203 | =================== 204 | 205 | * deps: type-is@~1.6.6 206 | - deps: mime-types@~2.1.4 207 | 208 | 1.13.2 / 2015-07-05 209 | =================== 210 | 211 | * deps: iconv-lite@0.4.11 212 | * deps: qs@4.0.0 213 | - Fix dropping parameters like `hasOwnProperty` 214 | - Fix user-visible incompatibilities from 3.1.0 215 | - Fix various parsing edge cases 216 | * deps: raw-body@~2.1.2 217 | - Fix error stack traces to skip `makeError` 218 | - deps: iconv-lite@0.4.11 219 | * deps: type-is@~1.6.4 220 | - deps: mime-types@~2.1.2 221 | - perf: enable strict mode 222 | - perf: remove argument reassignment 223 | 224 | 1.13.1 / 2015-06-16 225 | =================== 226 | 227 | * deps: qs@2.4.2 228 | - Downgraded from 3.1.0 because of user-visible incompatibilities 229 | 230 | 1.13.0 / 2015-06-14 231 | =================== 232 | 233 | * Add `statusCode` property on `Error`s, in addition to `status` 234 | * Change `type` default to `application/json` for JSON parser 235 | * Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser 236 | * Provide static `require` analysis 237 | * Use the `http-errors` module to generate errors 238 | * deps: bytes@2.1.0 239 | - Slight optimizations 240 | * deps: iconv-lite@0.4.10 241 | - The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails 242 | - Leading BOM is now removed when decoding 243 | * deps: on-finished@~2.3.0 244 | - Add defined behavior for HTTP `CONNECT` requests 245 | - Add defined behavior for HTTP `Upgrade` requests 246 | - deps: ee-first@1.1.1 247 | * deps: qs@3.1.0 248 | - Fix dropping parameters like `hasOwnProperty` 249 | - Fix various parsing edge cases 250 | - Parsed object now has `null` prototype 251 | * deps: raw-body@~2.1.1 252 | - Use `unpipe` module for unpiping requests 253 | - deps: iconv-lite@0.4.10 254 | * deps: type-is@~1.6.3 255 | - deps: mime-types@~2.1.1 256 | - perf: reduce try block size 257 | - perf: remove bitwise operations 258 | * perf: enable strict mode 259 | * perf: remove argument reassignment 260 | * perf: remove delete call 261 | 262 | 1.12.4 / 2015-05-10 263 | =================== 264 | 265 | * deps: debug@~2.2.0 266 | * deps: qs@2.4.2 267 | - Fix allowing parameters like `constructor` 268 | * deps: on-finished@~2.2.1 269 | * deps: raw-body@~2.0.1 270 | - Fix a false-positive when unpiping in Node.js 0.8 271 | - deps: bytes@2.0.1 272 | * deps: type-is@~1.6.2 273 | - deps: mime-types@~2.0.11 274 | 275 | 1.12.3 / 2015-04-15 276 | =================== 277 | 278 | * Slight efficiency improvement when not debugging 279 | * deps: depd@~1.0.1 280 | * deps: iconv-lite@0.4.8 281 | - Add encoding alias UNICODE-1-1-UTF-7 282 | * deps: raw-body@1.3.4 283 | - Fix hanging callback if request aborts during read 284 | - deps: iconv-lite@0.4.8 285 | 286 | 1.12.2 / 2015-03-16 287 | =================== 288 | 289 | * deps: qs@2.4.1 290 | - Fix error when parameter `hasOwnProperty` is present 291 | 292 | 1.12.1 / 2015-03-15 293 | =================== 294 | 295 | * deps: debug@~2.1.3 296 | - Fix high intensity foreground color for bold 297 | - deps: ms@0.7.0 298 | * deps: type-is@~1.6.1 299 | - deps: mime-types@~2.0.10 300 | 301 | 1.12.0 / 2015-02-13 302 | =================== 303 | 304 | * add `debug` messages 305 | * accept a function for the `type` option 306 | * use `content-type` to parse `Content-Type` headers 307 | * deps: iconv-lite@0.4.7 308 | - Gracefully support enumerables on `Object.prototype` 309 | * deps: raw-body@1.3.3 310 | - deps: iconv-lite@0.4.7 311 | * deps: type-is@~1.6.0 312 | - fix argument reassignment 313 | - fix false-positives in `hasBody` `Transfer-Encoding` check 314 | - support wildcard for both type and subtype (`*/*`) 315 | - deps: mime-types@~2.0.9 316 | 317 | 1.11.0 / 2015-01-30 318 | =================== 319 | 320 | * make internal `extended: true` depth limit infinity 321 | * deps: type-is@~1.5.6 322 | - deps: mime-types@~2.0.8 323 | 324 | 1.10.2 / 2015-01-20 325 | =================== 326 | 327 | * deps: iconv-lite@0.4.6 328 | - Fix rare aliases of single-byte encodings 329 | * deps: raw-body@1.3.2 330 | - deps: iconv-lite@0.4.6 331 | 332 | 1.10.1 / 2015-01-01 333 | =================== 334 | 335 | * deps: on-finished@~2.2.0 336 | * deps: type-is@~1.5.5 337 | - deps: mime-types@~2.0.7 338 | 339 | 1.10.0 / 2014-12-02 340 | =================== 341 | 342 | * make internal `extended: true` array limit dynamic 343 | 344 | 1.9.3 / 2014-11-21 345 | ================== 346 | 347 | * deps: iconv-lite@0.4.5 348 | - Fix Windows-31J and X-SJIS encoding support 349 | * deps: qs@2.3.3 350 | - Fix `arrayLimit` behavior 351 | * deps: raw-body@1.3.1 352 | - deps: iconv-lite@0.4.5 353 | * deps: type-is@~1.5.3 354 | - deps: mime-types@~2.0.3 355 | 356 | 1.9.2 / 2014-10-27 357 | ================== 358 | 359 | * deps: qs@2.3.2 360 | - Fix parsing of mixed objects and values 361 | 362 | 1.9.1 / 2014-10-22 363 | ================== 364 | 365 | * deps: on-finished@~2.1.1 366 | - Fix handling of pipelined requests 367 | * deps: qs@2.3.0 368 | - Fix parsing of mixed implicit and explicit arrays 369 | * deps: type-is@~1.5.2 370 | - deps: mime-types@~2.0.2 371 | 372 | 1.9.0 / 2014-09-24 373 | ================== 374 | 375 | * include the charset in "unsupported charset" error message 376 | * include the encoding in "unsupported content encoding" error message 377 | * deps: depd@~1.0.0 378 | 379 | 1.8.4 / 2014-09-23 380 | ================== 381 | 382 | * fix content encoding to be case-insensitive 383 | 384 | 1.8.3 / 2014-09-19 385 | ================== 386 | 387 | * deps: qs@2.2.4 388 | - Fix issue with object keys starting with numbers truncated 389 | 390 | 1.8.2 / 2014-09-15 391 | ================== 392 | 393 | * deps: depd@0.4.5 394 | 395 | 1.8.1 / 2014-09-07 396 | ================== 397 | 398 | * deps: media-typer@0.3.0 399 | * deps: type-is@~1.5.1 400 | 401 | 1.8.0 / 2014-09-05 402 | ================== 403 | 404 | * make empty-body-handling consistent between chunked requests 405 | - empty `json` produces `{}` 406 | - empty `raw` produces `new Buffer(0)` 407 | - empty `text` produces `''` 408 | - empty `urlencoded` produces `{}` 409 | * deps: qs@2.2.3 410 | - Fix issue where first empty value in array is discarded 411 | * deps: type-is@~1.5.0 412 | - fix `hasbody` to be true for `content-length: 0` 413 | 414 | 1.7.0 / 2014-09-01 415 | ================== 416 | 417 | * add `parameterLimit` option to `urlencoded` parser 418 | * change `urlencoded` extended array limit to 100 419 | * respond with 413 when over `parameterLimit` in `urlencoded` 420 | 421 | 1.6.7 / 2014-08-29 422 | ================== 423 | 424 | * deps: qs@2.2.2 425 | - Remove unnecessary cloning 426 | 427 | 1.6.6 / 2014-08-27 428 | ================== 429 | 430 | * deps: qs@2.2.0 431 | - Array parsing fix 432 | - Performance improvements 433 | 434 | 1.6.5 / 2014-08-16 435 | ================== 436 | 437 | * deps: on-finished@2.1.0 438 | 439 | 1.6.4 / 2014-08-14 440 | ================== 441 | 442 | * deps: qs@1.2.2 443 | 444 | 1.6.3 / 2014-08-10 445 | ================== 446 | 447 | * deps: qs@1.2.1 448 | 449 | 1.6.2 / 2014-08-07 450 | ================== 451 | 452 | * deps: qs@1.2.0 453 | - Fix parsing array of objects 454 | 455 | 1.6.1 / 2014-08-06 456 | ================== 457 | 458 | * deps: qs@1.1.0 459 | - Accept urlencoded square brackets 460 | - Accept empty values in implicit array notation 461 | 462 | 1.6.0 / 2014-08-05 463 | ================== 464 | 465 | * deps: qs@1.0.2 466 | - Complete rewrite 467 | - Limits array length to 20 468 | - Limits object depth to 5 469 | - Limits parameters to 1,000 470 | 471 | 1.5.2 / 2014-07-27 472 | ================== 473 | 474 | * deps: depd@0.4.4 475 | - Work-around v8 generating empty stack traces 476 | 477 | 1.5.1 / 2014-07-26 478 | ================== 479 | 480 | * deps: depd@0.4.3 481 | - Fix exception when global `Error.stackTraceLimit` is too low 482 | 483 | 1.5.0 / 2014-07-20 484 | ================== 485 | 486 | * deps: depd@0.4.2 487 | - Add `TRACE_DEPRECATION` environment variable 488 | - Remove non-standard grey color from color output 489 | - Support `--no-deprecation` argument 490 | - Support `--trace-deprecation` argument 491 | * deps: iconv-lite@0.4.4 492 | - Added encoding UTF-7 493 | * deps: raw-body@1.3.0 494 | - deps: iconv-lite@0.4.4 495 | - Added encoding UTF-7 496 | - Fix `Cannot switch to old mode now` error on Node.js 0.10+ 497 | * deps: type-is@~1.3.2 498 | 499 | 1.4.3 / 2014-06-19 500 | ================== 501 | 502 | * deps: type-is@1.3.1 503 | - fix global variable leak 504 | 505 | 1.4.2 / 2014-06-19 506 | ================== 507 | 508 | * deps: type-is@1.3.0 509 | - improve type parsing 510 | 511 | 1.4.1 / 2014-06-19 512 | ================== 513 | 514 | * fix urlencoded extended deprecation message 515 | 516 | 1.4.0 / 2014-06-19 517 | ================== 518 | 519 | * add `text` parser 520 | * add `raw` parser 521 | * check accepted charset in content-type (accepts utf-8) 522 | * check accepted encoding in content-encoding (accepts identity) 523 | * deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed 524 | * deprecate `urlencoded()` without provided `extended` option 525 | * lazy-load urlencoded parsers 526 | * parsers split into files for reduced mem usage 527 | * support gzip and deflate bodies 528 | - set `inflate: false` to turn off 529 | * deps: raw-body@1.2.2 530 | - Support all encodings from `iconv-lite` 531 | 532 | 1.3.1 / 2014-06-11 533 | ================== 534 | 535 | * deps: type-is@1.2.1 536 | - Switch dependency from mime to mime-types@1.0.0 537 | 538 | 1.3.0 / 2014-05-31 539 | ================== 540 | 541 | * add `extended` option to urlencoded parser 542 | 543 | 1.2.2 / 2014-05-27 544 | ================== 545 | 546 | * deps: raw-body@1.1.6 547 | - assert stream encoding on node.js 0.8 548 | - assert stream encoding on node.js < 0.10.6 549 | - deps: bytes@1 550 | 551 | 1.2.1 / 2014-05-26 552 | ================== 553 | 554 | * invoke `next(err)` after request fully read 555 | - prevents hung responses and socket hang ups 556 | 557 | 1.2.0 / 2014-05-11 558 | ================== 559 | 560 | * add `verify` option 561 | * deps: type-is@1.2.0 562 | - support suffix matching 563 | 564 | 1.1.2 / 2014-05-11 565 | ================== 566 | 567 | * improve json parser speed 568 | 569 | 1.1.1 / 2014-05-11 570 | ================== 571 | 572 | * fix repeated limit parsing with every request 573 | 574 | 1.1.0 / 2014-05-10 575 | ================== 576 | 577 | * add `type` option 578 | * deps: pin for safety and consistency 579 | 580 | 1.0.2 / 2014-04-14 581 | ================== 582 | 583 | * use `type-is` module 584 | 585 | 1.0.1 / 2014-03-20 586 | ================== 587 | 588 | * lower default limits to 100kb 589 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2014 Jonathan Ong 4 | Copyright (c) 2014-2015 Douglas Christopher Wilson 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | 'Software'), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 4 | * MIT Licensed 5 | */ 6 | 7 | 'use strict' 8 | 9 | /** 10 | * Module dependencies. 11 | * @private 12 | */ 13 | 14 | var deprecate = require('depd')('body-parser') 15 | 16 | /** 17 | * Cache of loaded parsers. 18 | * @private 19 | */ 20 | 21 | var parsers = Object.create(null) 22 | 23 | /** 24 | * @typedef Parsers 25 | * @type {function} 26 | * @property {function} json 27 | * @property {function} raw 28 | * @property {function} text 29 | * @property {function} urlencoded 30 | */ 31 | 32 | /** 33 | * Module exports. 34 | * @type {Parsers} 35 | */ 36 | 37 | exports = module.exports = deprecate.function(bodyParser, 38 | 'bodyParser: use individual json/urlencoded middlewares') 39 | 40 | /** 41 | * JSON parser. 42 | * @public 43 | */ 44 | 45 | Object.defineProperty(exports, 'json', { 46 | configurable: true, 47 | enumerable: true, 48 | get: createParserGetter('json') 49 | }) 50 | 51 | /** 52 | * Raw parser. 53 | * @public 54 | */ 55 | 56 | Object.defineProperty(exports, 'raw', { 57 | configurable: true, 58 | enumerable: true, 59 | get: createParserGetter('raw') 60 | }) 61 | 62 | /** 63 | * Text parser. 64 | * @public 65 | */ 66 | 67 | Object.defineProperty(exports, 'text', { 68 | configurable: true, 69 | enumerable: true, 70 | get: createParserGetter('text') 71 | }) 72 | 73 | /** 74 | * URL-encoded parser. 75 | * @public 76 | */ 77 | 78 | Object.defineProperty(exports, 'urlencoded', { 79 | configurable: true, 80 | enumerable: true, 81 | get: createParserGetter('urlencoded') 82 | }) 83 | 84 | /** 85 | * Create a middleware to parse json and urlencoded bodies. 86 | * 87 | * @param {object} [options] 88 | * @return {function} 89 | * @deprecated 90 | * @public 91 | */ 92 | 93 | function bodyParser (options) { 94 | var opts = {} 95 | 96 | // exclude type option 97 | if (options) { 98 | for (var prop in options) { 99 | if (prop !== 'type') { 100 | opts[prop] = options[prop] 101 | } 102 | } 103 | } 104 | 105 | var _urlencoded = exports.urlencoded(opts) 106 | var _json = exports.json(opts) 107 | 108 | return function bodyParser (req, res, next) { 109 | _json(req, res, function (err) { 110 | if (err) return next(err) 111 | _urlencoded(req, res, next) 112 | }) 113 | } 114 | } 115 | 116 | /** 117 | * Create a getter for loading a parser. 118 | * @private 119 | */ 120 | 121 | function createParserGetter (name) { 122 | return function get () { 123 | return loadParser(name) 124 | } 125 | } 126 | 127 | /** 128 | * Load a parser module. 129 | * @private 130 | */ 131 | 132 | function loadParser (parserName) { 133 | var parser = parsers[parserName] 134 | 135 | if (parser !== undefined) { 136 | return parser 137 | } 138 | 139 | // this uses a switch for static require analysis 140 | switch (parserName) { 141 | case 'json': 142 | parser = require('./lib/types/json') 143 | break 144 | case 'raw': 145 | parser = require('./lib/types/raw') 146 | break 147 | case 'text': 148 | parser = require('./lib/types/text') 149 | break 150 | case 'urlencoded': 151 | parser = require('./lib/types/urlencoded') 152 | break 153 | } 154 | 155 | // store to prevent invoking require() 156 | return (parsers[parserName] = parser) 157 | } 158 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/lib/read.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 4 | * MIT Licensed 5 | */ 6 | 7 | 'use strict' 8 | 9 | /** 10 | * Module dependencies. 11 | * @private 12 | */ 13 | 14 | var createError = require('http-errors') 15 | var getBody = require('raw-body') 16 | var iconv = require('iconv-lite') 17 | var onFinished = require('on-finished') 18 | var zlib = require('zlib') 19 | 20 | /** 21 | * Module exports. 22 | */ 23 | 24 | module.exports = read 25 | 26 | /** 27 | * Read a request into a buffer and parse. 28 | * 29 | * @param {object} req 30 | * @param {object} res 31 | * @param {function} next 32 | * @param {function} parse 33 | * @param {function} debug 34 | * @param {object} options 35 | * @private 36 | */ 37 | 38 | function read (req, res, next, parse, debug, options) { 39 | var length 40 | var opts = options 41 | var stream 42 | 43 | // flag as parsed 44 | req._body = true 45 | 46 | // read options 47 | var encoding = opts.encoding !== null 48 | ? opts.encoding 49 | : null 50 | var verify = opts.verify 51 | 52 | try { 53 | // get the content stream 54 | stream = contentstream(req, debug, opts.inflate) 55 | length = stream.length 56 | stream.length = undefined 57 | } catch (err) { 58 | return next(err) 59 | } 60 | 61 | // set raw-body options 62 | opts.length = length 63 | opts.encoding = verify 64 | ? null 65 | : encoding 66 | 67 | // assert charset is supported 68 | if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { 69 | return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { 70 | charset: encoding.toLowerCase(), 71 | type: 'charset.unsupported' 72 | })) 73 | } 74 | 75 | // read body 76 | debug('read body') 77 | getBody(stream, opts, function (error, body) { 78 | if (error) { 79 | var _error 80 | 81 | if (error.type === 'encoding.unsupported') { 82 | // echo back charset 83 | _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { 84 | charset: encoding.toLowerCase(), 85 | type: 'charset.unsupported' 86 | }) 87 | } else { 88 | // set status code on error 89 | _error = createError(400, error) 90 | } 91 | 92 | // read off entire request 93 | stream.resume() 94 | onFinished(req, function onfinished () { 95 | next(createError(400, _error)) 96 | }) 97 | return 98 | } 99 | 100 | // verify 101 | if (verify) { 102 | try { 103 | debug('verify body') 104 | verify(req, res, body, encoding) 105 | } catch (err) { 106 | next(createError(403, err, { 107 | body: body, 108 | type: err.type || 'entity.verify.failed' 109 | })) 110 | return 111 | } 112 | } 113 | 114 | // parse 115 | var str = body 116 | try { 117 | debug('parse body') 118 | str = typeof body !== 'string' && encoding !== null 119 | ? iconv.decode(body, encoding) 120 | : body 121 | req.body = parse(str) 122 | } catch (err) { 123 | next(createError(400, err, { 124 | body: str, 125 | type: err.type || 'entity.parse.failed' 126 | })) 127 | return 128 | } 129 | 130 | next() 131 | }) 132 | } 133 | 134 | /** 135 | * Get the content stream of the request. 136 | * 137 | * @param {object} req 138 | * @param {function} debug 139 | * @param {boolean} [inflate=true] 140 | * @return {object} 141 | * @api private 142 | */ 143 | 144 | function contentstream (req, debug, inflate) { 145 | var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() 146 | var length = req.headers['content-length'] 147 | var stream 148 | 149 | debug('content-encoding "%s"', encoding) 150 | 151 | if (inflate === false && encoding !== 'identity') { 152 | throw createError(415, 'content encoding unsupported', { 153 | encoding: encoding, 154 | type: 'encoding.unsupported' 155 | }) 156 | } 157 | 158 | switch (encoding) { 159 | case 'deflate': 160 | stream = zlib.createInflate() 161 | debug('inflate body') 162 | req.pipe(stream) 163 | break 164 | case 'gzip': 165 | stream = zlib.createGunzip() 166 | debug('gunzip body') 167 | req.pipe(stream) 168 | break 169 | case 'identity': 170 | stream = req 171 | stream.length = length 172 | break 173 | default: 174 | throw createError(415, 'unsupported content encoding "' + encoding + '"', { 175 | encoding: encoding, 176 | type: 'encoding.unsupported' 177 | }) 178 | } 179 | 180 | return stream 181 | } 182 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/lib/types/json.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014 Jonathan Ong 4 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | 'use strict' 9 | 10 | /** 11 | * Module dependencies. 12 | * @private 13 | */ 14 | 15 | var bytes = require('bytes') 16 | var contentType = require('content-type') 17 | var createError = require('http-errors') 18 | var debug = require('debug')('body-parser:json') 19 | var read = require('../read') 20 | var typeis = require('type-is') 21 | 22 | /** 23 | * Module exports. 24 | */ 25 | 26 | module.exports = json 27 | 28 | /** 29 | * RegExp to match the first non-space in a string. 30 | * 31 | * Allowed whitespace is defined in RFC 7159: 32 | * 33 | * ws = *( 34 | * %x20 / ; Space 35 | * %x09 / ; Horizontal tab 36 | * %x0A / ; Line feed or New line 37 | * %x0D ) ; Carriage return 38 | */ 39 | 40 | var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*(.)/ // eslint-disable-line no-control-regex 41 | 42 | /** 43 | * Create a middleware to parse JSON bodies. 44 | * 45 | * @param {object} [options] 46 | * @return {function} 47 | * @public 48 | */ 49 | 50 | function json (options) { 51 | var opts = options || {} 52 | 53 | var limit = typeof opts.limit !== 'number' 54 | ? bytes.parse(opts.limit || '100kb') 55 | : opts.limit 56 | var inflate = opts.inflate !== false 57 | var reviver = opts.reviver 58 | var strict = opts.strict !== false 59 | var type = opts.type || 'application/json' 60 | var verify = opts.verify || false 61 | 62 | if (verify !== false && typeof verify !== 'function') { 63 | throw new TypeError('option verify must be function') 64 | } 65 | 66 | // create the appropriate type checking function 67 | var shouldParse = typeof type !== 'function' 68 | ? typeChecker(type) 69 | : type 70 | 71 | function parse (body) { 72 | if (body.length === 0) { 73 | // special-case empty json body, as it's a common client-side mistake 74 | // TODO: maybe make this configurable or part of "strict" option 75 | return {} 76 | } 77 | 78 | if (strict) { 79 | var first = firstchar(body) 80 | 81 | if (first !== '{' && first !== '[') { 82 | debug('strict violation') 83 | throw createStrictSyntaxError(body, first) 84 | } 85 | } 86 | 87 | try { 88 | debug('parse json') 89 | return JSON.parse(body, reviver) 90 | } catch (e) { 91 | throw normalizeJsonSyntaxError(e, { 92 | message: e.message, 93 | stack: e.stack 94 | }) 95 | } 96 | } 97 | 98 | return function jsonParser (req, res, next) { 99 | if (req._body) { 100 | debug('body already parsed') 101 | next() 102 | return 103 | } 104 | 105 | req.body = req.body || {} 106 | 107 | // skip requests without bodies 108 | if (!typeis.hasBody(req)) { 109 | debug('skip empty body') 110 | next() 111 | return 112 | } 113 | 114 | debug('content-type %j', req.headers['content-type']) 115 | 116 | // determine if request should be parsed 117 | if (!shouldParse(req)) { 118 | debug('skip parsing') 119 | next() 120 | return 121 | } 122 | 123 | // assert charset per RFC 7159 sec 8.1 124 | var charset = getCharset(req) || 'utf-8' 125 | if (charset.substr(0, 4) !== 'utf-') { 126 | debug('invalid charset') 127 | next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { 128 | charset: charset, 129 | type: 'charset.unsupported' 130 | })) 131 | return 132 | } 133 | 134 | // read 135 | read(req, res, next, parse, debug, { 136 | encoding: charset, 137 | inflate: inflate, 138 | limit: limit, 139 | verify: verify 140 | }) 141 | } 142 | } 143 | 144 | /** 145 | * Create strict violation syntax error matching native error. 146 | * 147 | * @param {string} str 148 | * @param {string} char 149 | * @return {Error} 150 | * @private 151 | */ 152 | 153 | function createStrictSyntaxError (str, char) { 154 | var index = str.indexOf(char) 155 | var partial = str.substring(0, index) + '#' 156 | 157 | try { 158 | JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') 159 | } catch (e) { 160 | return normalizeJsonSyntaxError(e, { 161 | message: e.message.replace('#', char), 162 | stack: e.stack 163 | }) 164 | } 165 | } 166 | 167 | /** 168 | * Get the first non-whitespace character in a string. 169 | * 170 | * @param {string} str 171 | * @return {function} 172 | * @private 173 | */ 174 | 175 | function firstchar (str) { 176 | return FIRST_CHAR_REGEXP.exec(str)[1] 177 | } 178 | 179 | /** 180 | * Get the charset of a request. 181 | * 182 | * @param {object} req 183 | * @api private 184 | */ 185 | 186 | function getCharset (req) { 187 | try { 188 | return (contentType.parse(req).parameters.charset || '').toLowerCase() 189 | } catch (e) { 190 | return undefined 191 | } 192 | } 193 | 194 | /** 195 | * Normalize a SyntaxError for JSON.parse. 196 | * 197 | * @param {SyntaxError} error 198 | * @param {object} obj 199 | * @return {SyntaxError} 200 | */ 201 | 202 | function normalizeJsonSyntaxError (error, obj) { 203 | var keys = Object.getOwnPropertyNames(error) 204 | 205 | for (var i = 0; i < keys.length; i++) { 206 | var key = keys[i] 207 | if (key !== 'stack' && key !== 'message') { 208 | delete error[key] 209 | } 210 | } 211 | 212 | // replace stack before message for Node.js 0.10 and below 213 | error.stack = obj.stack.replace(error.message, obj.message) 214 | error.message = obj.message 215 | 216 | return error 217 | } 218 | 219 | /** 220 | * Get the simple type checker. 221 | * 222 | * @param {string} type 223 | * @return {function} 224 | */ 225 | 226 | function typeChecker (type) { 227 | return function checkType (req) { 228 | return Boolean(typeis(req, type)) 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/lib/types/raw.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 4 | * MIT Licensed 5 | */ 6 | 7 | 'use strict' 8 | 9 | /** 10 | * Module dependencies. 11 | */ 12 | 13 | var bytes = require('bytes') 14 | var debug = require('debug')('body-parser:raw') 15 | var read = require('../read') 16 | var typeis = require('type-is') 17 | 18 | /** 19 | * Module exports. 20 | */ 21 | 22 | module.exports = raw 23 | 24 | /** 25 | * Create a middleware to parse raw bodies. 26 | * 27 | * @param {object} [options] 28 | * @return {function} 29 | * @api public 30 | */ 31 | 32 | function raw (options) { 33 | var opts = options || {} 34 | 35 | var inflate = opts.inflate !== false 36 | var limit = typeof opts.limit !== 'number' 37 | ? bytes.parse(opts.limit || '100kb') 38 | : opts.limit 39 | var type = opts.type || 'application/octet-stream' 40 | var verify = opts.verify || false 41 | 42 | if (verify !== false && typeof verify !== 'function') { 43 | throw new TypeError('option verify must be function') 44 | } 45 | 46 | // create the appropriate type checking function 47 | var shouldParse = typeof type !== 'function' 48 | ? typeChecker(type) 49 | : type 50 | 51 | function parse (buf) { 52 | return buf 53 | } 54 | 55 | return function rawParser (req, res, next) { 56 | if (req._body) { 57 | debug('body already parsed') 58 | next() 59 | return 60 | } 61 | 62 | req.body = req.body || {} 63 | 64 | // skip requests without bodies 65 | if (!typeis.hasBody(req)) { 66 | debug('skip empty body') 67 | next() 68 | return 69 | } 70 | 71 | debug('content-type %j', req.headers['content-type']) 72 | 73 | // determine if request should be parsed 74 | if (!shouldParse(req)) { 75 | debug('skip parsing') 76 | next() 77 | return 78 | } 79 | 80 | // read 81 | read(req, res, next, parse, debug, { 82 | encoding: null, 83 | inflate: inflate, 84 | limit: limit, 85 | verify: verify 86 | }) 87 | } 88 | } 89 | 90 | /** 91 | * Get the simple type checker. 92 | * 93 | * @param {string} type 94 | * @return {function} 95 | */ 96 | 97 | function typeChecker (type) { 98 | return function checkType (req) { 99 | return Boolean(typeis(req, type)) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/lib/types/text.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 4 | * MIT Licensed 5 | */ 6 | 7 | 'use strict' 8 | 9 | /** 10 | * Module dependencies. 11 | */ 12 | 13 | var bytes = require('bytes') 14 | var contentType = require('content-type') 15 | var debug = require('debug')('body-parser:text') 16 | var read = require('../read') 17 | var typeis = require('type-is') 18 | 19 | /** 20 | * Module exports. 21 | */ 22 | 23 | module.exports = text 24 | 25 | /** 26 | * Create a middleware to parse text bodies. 27 | * 28 | * @param {object} [options] 29 | * @return {function} 30 | * @api public 31 | */ 32 | 33 | function text (options) { 34 | var opts = options || {} 35 | 36 | var defaultCharset = opts.defaultCharset || 'utf-8' 37 | var inflate = opts.inflate !== false 38 | var limit = typeof opts.limit !== 'number' 39 | ? bytes.parse(opts.limit || '100kb') 40 | : opts.limit 41 | var type = opts.type || 'text/plain' 42 | var verify = opts.verify || false 43 | 44 | if (verify !== false && typeof verify !== 'function') { 45 | throw new TypeError('option verify must be function') 46 | } 47 | 48 | // create the appropriate type checking function 49 | var shouldParse = typeof type !== 'function' 50 | ? typeChecker(type) 51 | : type 52 | 53 | function parse (buf) { 54 | return buf 55 | } 56 | 57 | return function textParser (req, res, next) { 58 | if (req._body) { 59 | debug('body already parsed') 60 | next() 61 | return 62 | } 63 | 64 | req.body = req.body || {} 65 | 66 | // skip requests without bodies 67 | if (!typeis.hasBody(req)) { 68 | debug('skip empty body') 69 | next() 70 | return 71 | } 72 | 73 | debug('content-type %j', req.headers['content-type']) 74 | 75 | // determine if request should be parsed 76 | if (!shouldParse(req)) { 77 | debug('skip parsing') 78 | next() 79 | return 80 | } 81 | 82 | // get charset 83 | var charset = getCharset(req) || defaultCharset 84 | 85 | // read 86 | read(req, res, next, parse, debug, { 87 | encoding: charset, 88 | inflate: inflate, 89 | limit: limit, 90 | verify: verify 91 | }) 92 | } 93 | } 94 | 95 | /** 96 | * Get the charset of a request. 97 | * 98 | * @param {object} req 99 | * @api private 100 | */ 101 | 102 | function getCharset (req) { 103 | try { 104 | return (contentType.parse(req).parameters.charset || '').toLowerCase() 105 | } catch (e) { 106 | return undefined 107 | } 108 | } 109 | 110 | /** 111 | * Get the simple type checker. 112 | * 113 | * @param {string} type 114 | * @return {function} 115 | */ 116 | 117 | function typeChecker (type) { 118 | return function checkType (req) { 119 | return Boolean(typeis(req, type)) 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/lib/types/urlencoded.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * body-parser 3 | * Copyright(c) 2014 Jonathan Ong 4 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | 'use strict' 9 | 10 | /** 11 | * Module dependencies. 12 | * @private 13 | */ 14 | 15 | var bytes = require('bytes') 16 | var contentType = require('content-type') 17 | var createError = require('http-errors') 18 | var debug = require('debug')('body-parser:urlencoded') 19 | var deprecate = require('depd')('body-parser') 20 | var read = require('../read') 21 | var typeis = require('type-is') 22 | 23 | /** 24 | * Module exports. 25 | */ 26 | 27 | module.exports = urlencoded 28 | 29 | /** 30 | * Cache of parser modules. 31 | */ 32 | 33 | var parsers = Object.create(null) 34 | 35 | /** 36 | * Create a middleware to parse urlencoded bodies. 37 | * 38 | * @param {object} [options] 39 | * @return {function} 40 | * @public 41 | */ 42 | 43 | function urlencoded (options) { 44 | var opts = options || {} 45 | 46 | // notice because option default will flip in next major 47 | if (opts.extended === undefined) { 48 | deprecate('undefined extended: provide extended option') 49 | } 50 | 51 | var extended = opts.extended !== false 52 | var inflate = opts.inflate !== false 53 | var limit = typeof opts.limit !== 'number' 54 | ? bytes.parse(opts.limit || '100kb') 55 | : opts.limit 56 | var type = opts.type || 'application/x-www-form-urlencoded' 57 | var verify = opts.verify || false 58 | 59 | if (verify !== false && typeof verify !== 'function') { 60 | throw new TypeError('option verify must be function') 61 | } 62 | 63 | // create the appropriate query parser 64 | var queryparse = extended 65 | ? extendedparser(opts) 66 | : simpleparser(opts) 67 | 68 | // create the appropriate type checking function 69 | var shouldParse = typeof type !== 'function' 70 | ? typeChecker(type) 71 | : type 72 | 73 | function parse (body) { 74 | return body.length 75 | ? queryparse(body) 76 | : {} 77 | } 78 | 79 | return function urlencodedParser (req, res, next) { 80 | if (req._body) { 81 | debug('body already parsed') 82 | next() 83 | return 84 | } 85 | 86 | req.body = req.body || {} 87 | 88 | // skip requests without bodies 89 | if (!typeis.hasBody(req)) { 90 | debug('skip empty body') 91 | next() 92 | return 93 | } 94 | 95 | debug('content-type %j', req.headers['content-type']) 96 | 97 | // determine if request should be parsed 98 | if (!shouldParse(req)) { 99 | debug('skip parsing') 100 | next() 101 | return 102 | } 103 | 104 | // assert charset 105 | var charset = getCharset(req) || 'utf-8' 106 | if (charset !== 'utf-8') { 107 | debug('invalid charset') 108 | next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { 109 | charset: charset, 110 | type: 'charset.unsupported' 111 | })) 112 | return 113 | } 114 | 115 | // read 116 | read(req, res, next, parse, debug, { 117 | debug: debug, 118 | encoding: charset, 119 | inflate: inflate, 120 | limit: limit, 121 | verify: verify 122 | }) 123 | } 124 | } 125 | 126 | /** 127 | * Get the extended query parser. 128 | * 129 | * @param {object} options 130 | */ 131 | 132 | function extendedparser (options) { 133 | var parameterLimit = options.parameterLimit !== undefined 134 | ? options.parameterLimit 135 | : 1000 136 | var parse = parser('qs') 137 | 138 | if (isNaN(parameterLimit) || parameterLimit < 1) { 139 | throw new TypeError('option parameterLimit must be a positive number') 140 | } 141 | 142 | if (isFinite(parameterLimit)) { 143 | parameterLimit = parameterLimit | 0 144 | } 145 | 146 | return function queryparse (body) { 147 | var paramCount = parameterCount(body, parameterLimit) 148 | 149 | if (paramCount === undefined) { 150 | debug('too many parameters') 151 | throw createError(413, 'too many parameters', { 152 | type: 'parameters.too.many' 153 | }) 154 | } 155 | 156 | var arrayLimit = Math.max(100, paramCount) 157 | 158 | debug('parse extended urlencoding') 159 | return parse(body, { 160 | allowPrototypes: true, 161 | arrayLimit: arrayLimit, 162 | depth: Infinity, 163 | parameterLimit: parameterLimit 164 | }) 165 | } 166 | } 167 | 168 | /** 169 | * Get the charset of a request. 170 | * 171 | * @param {object} req 172 | * @api private 173 | */ 174 | 175 | function getCharset (req) { 176 | try { 177 | return (contentType.parse(req).parameters.charset || '').toLowerCase() 178 | } catch (e) { 179 | return undefined 180 | } 181 | } 182 | 183 | /** 184 | * Count the number of parameters, stopping once limit reached 185 | * 186 | * @param {string} body 187 | * @param {number} limit 188 | * @api private 189 | */ 190 | 191 | function parameterCount (body, limit) { 192 | var count = 0 193 | var index = 0 194 | 195 | while ((index = body.indexOf('&', index)) !== -1) { 196 | count++ 197 | index++ 198 | 199 | if (count === limit) { 200 | return undefined 201 | } 202 | } 203 | 204 | return count 205 | } 206 | 207 | /** 208 | * Get parser for module name dynamically. 209 | * 210 | * @param {string} name 211 | * @return {function} 212 | * @api private 213 | */ 214 | 215 | function parser (name) { 216 | var mod = parsers[name] 217 | 218 | if (mod !== undefined) { 219 | return mod.parse 220 | } 221 | 222 | // this uses a switch for static require analysis 223 | switch (name) { 224 | case 'qs': 225 | mod = require('qs') 226 | break 227 | case 'querystring': 228 | mod = require('querystring') 229 | break 230 | } 231 | 232 | // store to prevent invoking require() 233 | parsers[name] = mod 234 | 235 | return mod.parse 236 | } 237 | 238 | /** 239 | * Get the simple query parser. 240 | * 241 | * @param {object} options 242 | */ 243 | 244 | function simpleparser (options) { 245 | var parameterLimit = options.parameterLimit !== undefined 246 | ? options.parameterLimit 247 | : 1000 248 | var parse = parser('querystring') 249 | 250 | if (isNaN(parameterLimit) || parameterLimit < 1) { 251 | throw new TypeError('option parameterLimit must be a positive number') 252 | } 253 | 254 | if (isFinite(parameterLimit)) { 255 | parameterLimit = parameterLimit | 0 256 | } 257 | 258 | return function queryparse (body) { 259 | var paramCount = parameterCount(body, parameterLimit) 260 | 261 | if (paramCount === undefined) { 262 | debug('too many parameters') 263 | throw createError(413, 'too many parameters', { 264 | type: 'parameters.too.many' 265 | }) 266 | } 267 | 268 | debug('parse urlencoding') 269 | return parse(body, undefined, undefined, {maxKeys: parameterLimit}) 270 | } 271 | } 272 | 273 | /** 274 | * Get the simple type checker. 275 | * 276 | * @param {string} type 277 | * @return {function} 278 | */ 279 | 280 | function typeChecker (type) { 281 | return function checkType (req) { 282 | return Boolean(typeis(req, type)) 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /nodejs/node_modules/body-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body-parser", 3 | "description": "Node.js body parsing middleware", 4 | "version": "1.18.3", 5 | "contributors": [ 6 | "Douglas Christopher Wilson ", 7 | "Jonathan Ong (http://jongleberry.com)" 8 | ], 9 | "license": "MIT", 10 | "repository": "expressjs/body-parser", 11 | "dependencies": { 12 | "bytes": "3.0.0", 13 | "content-type": "~1.0.4", 14 | "debug": "2.6.9", 15 | "depd": "~1.1.2", 16 | "http-errors": "~1.6.3", 17 | "iconv-lite": "0.4.23", 18 | "on-finished": "~2.3.0", 19 | "qs": "6.5.2", 20 | "raw-body": "2.3.3", 21 | "type-is": "~1.6.16" 22 | }, 23 | "devDependencies": { 24 | "eslint": "4.19.1", 25 | "eslint-config-standard": "11.0.0", 26 | "eslint-plugin-import": "2.11.0", 27 | "eslint-plugin-markdown": "1.0.0-beta.6", 28 | "eslint-plugin-node": "6.0.1", 29 | "eslint-plugin-promise": "3.7.0", 30 | "eslint-plugin-standard": "3.1.0", 31 | "istanbul": "0.4.5", 32 | "methods": "1.1.2", 33 | "mocha": "2.5.3", 34 | "safe-buffer": "5.1.2", 35 | "supertest": "1.1.0" 36 | }, 37 | "files": [ 38 | "lib/", 39 | "LICENSE", 40 | "HISTORY.md", 41 | "index.js" 42 | ], 43 | "engines": { 44 | "node": ">= 0.8" 45 | }, 46 | "scripts": { 47 | "lint": "eslint --plugin markdown --ext js,md .", 48 | "test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/", 49 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/", 50 | "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/HISTORY.md: -------------------------------------------------------------------------------- 1 | 1.4.5 / 2020-03-14 2 | ================== 3 | 4 | * deps: cookie@0.4.0 5 | 6 | 1.4.4 / 2019-02-12 7 | ================== 8 | 9 | * perf: normalize `secret` argument only once 10 | 11 | 1.4.3 / 2016-05-26 12 | ================== 13 | 14 | * deps: cookie@0.3.1 15 | - perf: use for loop in parse 16 | 17 | 1.4.2 / 2016-05-20 18 | ================== 19 | 20 | * deps: cookie@0.2.4 21 | - perf: enable strict mode 22 | - perf: use for loop in parse 23 | - perf: use string concatenation for serialization 24 | 25 | 1.4.1 / 2016-01-11 26 | ================== 27 | 28 | * deps: cookie@0.2.3 29 | * perf: enable strict mode 30 | 31 | 1.4.0 / 2015-09-18 32 | ================== 33 | 34 | * Accept array of secrets in addition to a single secret 35 | * Fix `JSONCookie` to return `undefined` for non-string arguments 36 | * Fix `signedCookie` to return `undefined` for non-string arguments 37 | * deps: cookie@0.2.2 38 | 39 | 1.3.5 / 2015-05-19 40 | ================== 41 | 42 | * deps: cookie@0.1.3 43 | - Slight optimizations 44 | 45 | 1.3.4 / 2015-02-15 46 | ================== 47 | 48 | * deps: cookie-signature@1.0.6 49 | 50 | 1.3.3 / 2014-09-05 51 | ================== 52 | 53 | * deps: cookie-signature@1.0.5 54 | 55 | 1.3.2 / 2014-06-26 56 | ================== 57 | 58 | * deps: cookie-signature@1.0.4 59 | - fix for timing attacks 60 | 61 | 1.3.1 / 2014-06-17 62 | ================== 63 | 64 | * actually export `signedCookie` 65 | 66 | 1.3.0 / 2014-06-17 67 | ================== 68 | 69 | * add `signedCookie` export for single cookie unsigning 70 | 71 | 1.2.0 / 2014-06-17 72 | ================== 73 | 74 | * export parsing functions 75 | * `req.cookies` and `req.signedCookies` are now plain objects 76 | * slightly faster parsing of many cookies 77 | 78 | 1.1.0 / 2014-05-12 79 | ================== 80 | 81 | * Support for NodeJS version 0.8 82 | * deps: cookie@0.1.2 83 | - Fix for maxAge == 0 84 | - made compat with expires field 85 | - tweak maxAge NaN error message 86 | 87 | 1.0.1 / 2014-02-20 88 | ================== 89 | 90 | * add missing dependencies 91 | 92 | 1.0.0 / 2014-02-15 93 | ================== 94 | 95 | * Genesis from `connect` 96 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2014 TJ Holowaychuk 4 | Copyright (c) 2015 Douglas Christopher Wilson 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | 'Software'), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/README.md: -------------------------------------------------------------------------------- 1 | # cookie-parser 2 | 3 | [![NPM Version][npm-version-image]][npm-url] 4 | [![NPM Downloads][npm-downloads-image]][npm-url] 5 | [![Build Status][travis-image]][travis-url] 6 | [![Test Coverage][coveralls-image]][coveralls-url] 7 | 8 | Parse `Cookie` header and populate `req.cookies` with an object keyed by the 9 | cookie names. Optionally you may enable signed cookie support by passing a 10 | `secret` string, which assigns `req.secret` so it may be used by other 11 | middleware. 12 | 13 | ## Installation 14 | 15 | ```sh 16 | $ npm install cookie-parser 17 | ``` 18 | 19 | ## API 20 | 21 | ```js 22 | var express = require('express') 23 | var cookieParser = require('cookie-parser') 24 | 25 | var app = express() 26 | app.use(cookieParser()) 27 | ``` 28 | 29 | ### cookieParser(secret, options) 30 | 31 | - `secret` a string or array used for signing cookies. This is optional and if 32 | not specified, will not parse signed cookies. If a string is provided, this 33 | is used as the secret. If an array is provided, an attempt will be made to 34 | unsign the cookie with each secret in order. 35 | - `options` an object that is passed to `cookie.parse` as the second option. Se 36 | [cookie](https://www.npmjs.org/package/cookie) for more information. 37 | - `decode` a function to decode the value of the cookie 38 | 39 | ### cookieParser.JSONCookie(str) 40 | 41 | Parse a cookie value as a JSON cookie. This will return the parsed JSON value 42 | if it was a JSON cookie, otherwise, it will return the passed value. 43 | 44 | ### cookieParser.JSONCookies(cookies) 45 | 46 | Given an object, this will iterate over the keys and call `JSONCookie` on each 47 | value, replacing the original value with the parsed value. This returns the 48 | same object that was passed in. 49 | 50 | ### cookieParser.signedCookie(str, secret) 51 | 52 | Parse a cookie value as a signed cookie. This will return the parsed unsigned 53 | value if it was a signed cookie and the signature was valid. If the value was 54 | not signed, the original value is returned. If the value was signed but the 55 | signature could not be validated, `false` is returned. 56 | 57 | The `secret` argument can be an array or string. If a string is provided, this 58 | is used as the secret. If an array is provided, an attempt will be made to 59 | unsign the cookie with each secret in order. 60 | 61 | ### cookieParser.signedCookies(cookies, secret) 62 | 63 | Given an object, this will iterate over the keys and check if any value is a 64 | signed cookie. If it is a signed cookie and the signature is valid, the key 65 | will be deleted from the object and added to the new object that is returned. 66 | 67 | The `secret` argument can be an array or string. If a string is provided, this 68 | is used as the secret. If an array is provided, an attempt will be made to 69 | unsign the cookie with each secret in order. 70 | 71 | ## Example 72 | 73 | ```js 74 | var express = require('express') 75 | var cookieParser = require('cookie-parser') 76 | 77 | var app = express() 78 | app.use(cookieParser()) 79 | 80 | app.get('/', function (req, res) { 81 | // Cookies that have not been signed 82 | console.log('Cookies: ', req.cookies) 83 | 84 | // Cookies that have been signed 85 | console.log('Signed Cookies: ', req.signedCookies) 86 | }) 87 | 88 | app.listen(8080) 89 | 90 | // curl command that sends an HTTP request with two cookies 91 | // curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello" 92 | ``` 93 | 94 | ### [MIT Licensed](LICENSE) 95 | 96 | [coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/cookie-parser/master 97 | [coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master 98 | [npm-downloads-image]: https://badgen.net/npm/dm/cookie-parser 99 | [npm-url]: https://npmjs.org/package/cookie-parser 100 | [npm-version-image]: https://badgen.net/npm/v/cookie-parser 101 | [travis-image]: https://badgen.net/travis/expressjs/cookie-parser/master 102 | [travis-url]: https://travis-ci.org/expressjs/cookie-parser 103 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * cookie-parser 3 | * Copyright(c) 2014 TJ Holowaychuk 4 | * Copyright(c) 2015 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | 'use strict' 9 | 10 | /** 11 | * Module dependencies. 12 | * @private 13 | */ 14 | 15 | var cookie = require('cookie') 16 | var signature = require('cookie-signature') 17 | 18 | /** 19 | * Module exports. 20 | * @public 21 | */ 22 | 23 | module.exports = cookieParser 24 | module.exports.JSONCookie = JSONCookie 25 | module.exports.JSONCookies = JSONCookies 26 | module.exports.signedCookie = signedCookie 27 | module.exports.signedCookies = signedCookies 28 | 29 | /** 30 | * Parse Cookie header and populate `req.cookies` 31 | * with an object keyed by the cookie names. 32 | * 33 | * @param {string|array} [secret] A string (or array of strings) representing cookie signing secret(s). 34 | * @param {Object} [options] 35 | * @return {Function} 36 | * @public 37 | */ 38 | 39 | function cookieParser (secret, options) { 40 | var secrets = !secret || Array.isArray(secret) 41 | ? (secret || []) 42 | : [secret] 43 | 44 | return function cookieParser (req, res, next) { 45 | if (req.cookies) { 46 | return next() 47 | } 48 | 49 | var cookies = req.headers.cookie 50 | 51 | req.secret = secrets[0] 52 | req.cookies = Object.create(null) 53 | req.signedCookies = Object.create(null) 54 | 55 | // no cookies 56 | if (!cookies) { 57 | return next() 58 | } 59 | 60 | req.cookies = cookie.parse(cookies, options) 61 | 62 | // parse signed cookies 63 | if (secrets.length !== 0) { 64 | req.signedCookies = signedCookies(req.cookies, secrets) 65 | req.signedCookies = JSONCookies(req.signedCookies) 66 | } 67 | 68 | // parse JSON cookies 69 | req.cookies = JSONCookies(req.cookies) 70 | 71 | next() 72 | } 73 | } 74 | 75 | /** 76 | * Parse JSON cookie string. 77 | * 78 | * @param {String} str 79 | * @return {Object} Parsed object or undefined if not json cookie 80 | * @public 81 | */ 82 | 83 | function JSONCookie (str) { 84 | if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') { 85 | return undefined 86 | } 87 | 88 | try { 89 | return JSON.parse(str.slice(2)) 90 | } catch (err) { 91 | return undefined 92 | } 93 | } 94 | 95 | /** 96 | * Parse JSON cookies. 97 | * 98 | * @param {Object} obj 99 | * @return {Object} 100 | * @public 101 | */ 102 | 103 | function JSONCookies (obj) { 104 | var cookies = Object.keys(obj) 105 | var key 106 | var val 107 | 108 | for (var i = 0; i < cookies.length; i++) { 109 | key = cookies[i] 110 | val = JSONCookie(obj[key]) 111 | 112 | if (val) { 113 | obj[key] = val 114 | } 115 | } 116 | 117 | return obj 118 | } 119 | 120 | /** 121 | * Parse a signed cookie string, return the decoded value. 122 | * 123 | * @param {String} str signed cookie string 124 | * @param {string|array} secret 125 | * @return {String} decoded value 126 | * @public 127 | */ 128 | 129 | function signedCookie (str, secret) { 130 | if (typeof str !== 'string') { 131 | return undefined 132 | } 133 | 134 | if (str.substr(0, 2) !== 's:') { 135 | return str 136 | } 137 | 138 | var secrets = !secret || Array.isArray(secret) 139 | ? (secret || []) 140 | : [secret] 141 | 142 | for (var i = 0; i < secrets.length; i++) { 143 | var val = signature.unsign(str.slice(2), secrets[i]) 144 | 145 | if (val !== false) { 146 | return val 147 | } 148 | } 149 | 150 | return false 151 | } 152 | 153 | /** 154 | * Parse signed cookies, returning an object containing the decoded key/value 155 | * pairs, while removing the signed key from obj. 156 | * 157 | * @param {Object} obj 158 | * @param {string|array} secret 159 | * @return {Object} 160 | * @public 161 | */ 162 | 163 | function signedCookies (obj, secret) { 164 | var cookies = Object.keys(obj) 165 | var dec 166 | var key 167 | var ret = Object.create(null) 168 | var val 169 | 170 | for (var i = 0; i < cookies.length; i++) { 171 | key = cookies[i] 172 | val = obj[key] 173 | dec = signedCookie(val, secret) 174 | 175 | if (val !== dec) { 176 | ret[key] = dec 177 | delete obj[key] 178 | } 179 | } 180 | 181 | return ret 182 | } 183 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/node_modules/cookie/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012-2014 Roman Shtylman 4 | Copyright (c) 2015 Douglas Christopher Wilson 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | 'Software'), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/node_modules/cookie/README.md: -------------------------------------------------------------------------------- 1 | # cookie 2 | 3 | [![NPM Version][npm-version-image]][npm-url] 4 | [![NPM Downloads][npm-downloads-image]][npm-url] 5 | [![Node.js Version][node-version-image]][node-version-url] 6 | [![Build Status][travis-image]][travis-url] 7 | [![Test Coverage][coveralls-image]][coveralls-url] 8 | 9 | Basic HTTP cookie parser and serializer for HTTP servers. 10 | 11 | ## Installation 12 | 13 | ```sh 14 | $ npm install cookie 15 | ``` 16 | 17 | ## API 18 | 19 | ```js 20 | var cookie = require('cookie'); 21 | ``` 22 | 23 | ### cookie.parse(str, options) 24 | 25 | Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs. 26 | The `str` argument is the string representing a `Cookie` header value and `options` is an 27 | optional object containing additional parsing options. 28 | 29 | ```js 30 | var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2'); 31 | // { foo: 'bar', equation: 'E=mc^2' } 32 | ``` 33 | 34 | #### Options 35 | 36 | `cookie.parse` accepts these properties in the options object. 37 | 38 | ##### decode 39 | 40 | Specifies a function that will be used to decode a cookie's value. Since the value of a cookie 41 | has a limited character set (and must be a simple string), this function can be used to decode 42 | a previously-encoded cookie value into a JavaScript string or other object. 43 | 44 | The default function is the global `decodeURIComponent`, which will decode any URL-encoded 45 | sequences into their byte representations. 46 | 47 | **note** if an error is thrown from this function, the original, non-decoded cookie value will 48 | be returned as the cookie's value. 49 | 50 | ### cookie.serialize(name, value, options) 51 | 52 | Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the 53 | name for the cookie, the `value` argument is the value to set the cookie to, and the `options` 54 | argument is an optional object containing additional serialization options. 55 | 56 | ```js 57 | var setCookie = cookie.serialize('foo', 'bar'); 58 | // foo=bar 59 | ``` 60 | 61 | #### Options 62 | 63 | `cookie.serialize` accepts these properties in the options object. 64 | 65 | ##### domain 66 | 67 | Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no 68 | domain is set, and most clients will consider the cookie to apply to only the current domain. 69 | 70 | ##### encode 71 | 72 | Specifies a function that will be used to encode a cookie's value. Since value of a cookie 73 | has a limited character set (and must be a simple string), this function can be used to encode 74 | a value into a string suited for a cookie's value. 75 | 76 | The default function is the global `encodeURIComponent`, which will encode a JavaScript string 77 | into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range. 78 | 79 | ##### expires 80 | 81 | Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1]. 82 | By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and 83 | will delete it on a condition like exiting a web browser application. 84 | 85 | **note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and 86 | `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, 87 | so if both are set, they should point to the same date and time. 88 | 89 | ##### httpOnly 90 | 91 | Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy, 92 | the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set. 93 | 94 | **note** be careful when setting this to `true`, as compliant clients will not allow client-side 95 | JavaScript to see the cookie in `document.cookie`. 96 | 97 | ##### maxAge 98 | 99 | Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2]. 100 | The given number will be converted to an integer by rounding down. By default, no maximum age is set. 101 | 102 | **note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and 103 | `maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, 104 | so if both are set, they should point to the same date and time. 105 | 106 | ##### path 107 | 108 | Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path 109 | is considered the ["default path"][rfc-6265-5.1.4]. 110 | 111 | ##### sameSite 112 | 113 | Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-03-4.1.2.7]. 114 | 115 | - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. 116 | - `false` will not set the `SameSite` attribute. 117 | - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. 118 | - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. 119 | - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. 120 | 121 | More information about the different enforcement levels can be found in 122 | [the specification][rfc-6265bis-03-4.1.2.7]. 123 | 124 | **note** This is an attribute that has not yet been fully standardized, and may change in the future. 125 | This also means many clients may ignore this attribute until they understand it. 126 | 127 | ##### secure 128 | 129 | Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy, 130 | the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set. 131 | 132 | **note** be careful when setting this to `true`, as compliant clients will not send the cookie back to 133 | the server in the future if the browser does not have an HTTPS connection. 134 | 135 | ## Example 136 | 137 | The following example uses this module in conjunction with the Node.js core HTTP server 138 | to prompt a user for their name and display it back on future visits. 139 | 140 | ```js 141 | var cookie = require('cookie'); 142 | var escapeHtml = require('escape-html'); 143 | var http = require('http'); 144 | var url = require('url'); 145 | 146 | function onRequest(req, res) { 147 | // Parse the query string 148 | var query = url.parse(req.url, true, true).query; 149 | 150 | if (query && query.name) { 151 | // Set a new cookie with the name 152 | res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), { 153 | httpOnly: true, 154 | maxAge: 60 * 60 * 24 * 7 // 1 week 155 | })); 156 | 157 | // Redirect back after setting cookie 158 | res.statusCode = 302; 159 | res.setHeader('Location', req.headers.referer || '/'); 160 | res.end(); 161 | return; 162 | } 163 | 164 | // Parse the cookies on the request 165 | var cookies = cookie.parse(req.headers.cookie || ''); 166 | 167 | // Get the visitor name set in the cookie 168 | var name = cookies.name; 169 | 170 | res.setHeader('Content-Type', 'text/html; charset=UTF-8'); 171 | 172 | if (name) { 173 | res.write('

Welcome back, ' + escapeHtml(name) + '!

'); 174 | } else { 175 | res.write('

Hello, new visitor!

'); 176 | } 177 | 178 | res.write('
'); 179 | res.write(' '); 180 | res.end('
'); 181 | } 182 | 183 | http.createServer(onRequest).listen(3000); 184 | ``` 185 | 186 | ## Testing 187 | 188 | ```sh 189 | $ npm test 190 | ``` 191 | 192 | ## Benchmark 193 | 194 | ``` 195 | $ npm run bench 196 | 197 | > cookie@0.3.1 bench cookie 198 | > node benchmark/index.js 199 | 200 | http_parser@2.8.0 201 | node@6.14.2 202 | v8@5.1.281.111 203 | uv@1.16.1 204 | zlib@1.2.11 205 | ares@1.10.1-DEV 206 | icu@58.2 207 | modules@48 208 | napi@3 209 | openssl@1.0.2o 210 | 211 | > node benchmark/parse.js 212 | 213 | cookie.parse 214 | 215 | 6 tests completed. 216 | 217 | simple x 1,200,691 ops/sec ±1.12% (189 runs sampled) 218 | decode x 1,012,994 ops/sec ±0.97% (186 runs sampled) 219 | unquote x 1,074,174 ops/sec ±2.43% (186 runs sampled) 220 | duplicates x 438,424 ops/sec ±2.17% (184 runs sampled) 221 | 10 cookies x 147,154 ops/sec ±1.01% (186 runs sampled) 222 | 100 cookies x 14,274 ops/sec ±1.07% (187 runs sampled) 223 | ``` 224 | 225 | ## References 226 | 227 | - [RFC 6265: HTTP State Management Mechanism][rfc-6265] 228 | - [Same-site Cookies][rfc-6265bis-03-4.1.2.7] 229 | 230 | [rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 231 | [rfc-6265]: https://tools.ietf.org/html/rfc6265 232 | [rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4 233 | [rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1 234 | [rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2 235 | [rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3 236 | [rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4 237 | [rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5 238 | [rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6 239 | [rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3 240 | 241 | ## License 242 | 243 | [MIT](LICENSE) 244 | 245 | [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master 246 | [coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master 247 | [node-version-image]: https://badgen.net/npm/node/cookie 248 | [node-version-url]: https://nodejs.org/en/download 249 | [npm-downloads-image]: https://badgen.net/npm/dm/cookie 250 | [npm-url]: https://npmjs.org/package/cookie 251 | [npm-version-image]: https://badgen.net/npm/v/cookie 252 | [travis-image]: https://badgen.net/travis/jshttp/cookie/master 253 | [travis-url]: https://travis-ci.org/jshttp/cookie 254 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/node_modules/cookie/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * cookie 3 | * Copyright(c) 2012-2014 Roman Shtylman 4 | * Copyright(c) 2015 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * Module exports. 12 | * @public 13 | */ 14 | 15 | exports.parse = parse; 16 | exports.serialize = serialize; 17 | 18 | /** 19 | * Module variables. 20 | * @private 21 | */ 22 | 23 | var decode = decodeURIComponent; 24 | var encode = encodeURIComponent; 25 | var pairSplitRegExp = /; */; 26 | 27 | /** 28 | * RegExp to match field-content in RFC 7230 sec 3.2 29 | * 30 | * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] 31 | * field-vchar = VCHAR / obs-text 32 | * obs-text = %x80-FF 33 | */ 34 | 35 | var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; 36 | 37 | /** 38 | * Parse a cookie header. 39 | * 40 | * Parse the given cookie header string into an object 41 | * The object has the various cookies as keys(names) => values 42 | * 43 | * @param {string} str 44 | * @param {object} [options] 45 | * @return {object} 46 | * @public 47 | */ 48 | 49 | function parse(str, options) { 50 | if (typeof str !== 'string') { 51 | throw new TypeError('argument str must be a string'); 52 | } 53 | 54 | var obj = {} 55 | var opt = options || {}; 56 | var pairs = str.split(pairSplitRegExp); 57 | var dec = opt.decode || decode; 58 | 59 | for (var i = 0; i < pairs.length; i++) { 60 | var pair = pairs[i]; 61 | var eq_idx = pair.indexOf('='); 62 | 63 | // skip things that don't look like key=value 64 | if (eq_idx < 0) { 65 | continue; 66 | } 67 | 68 | var key = pair.substr(0, eq_idx).trim() 69 | var val = pair.substr(++eq_idx, pair.length).trim(); 70 | 71 | // quoted values 72 | if ('"' == val[0]) { 73 | val = val.slice(1, -1); 74 | } 75 | 76 | // only assign once 77 | if (undefined == obj[key]) { 78 | obj[key] = tryDecode(val, dec); 79 | } 80 | } 81 | 82 | return obj; 83 | } 84 | 85 | /** 86 | * Serialize data into a cookie header. 87 | * 88 | * Serialize the a name value pair into a cookie string suitable for 89 | * http headers. An optional options object specified cookie parameters. 90 | * 91 | * serialize('foo', 'bar', { httpOnly: true }) 92 | * => "foo=bar; httpOnly" 93 | * 94 | * @param {string} name 95 | * @param {string} val 96 | * @param {object} [options] 97 | * @return {string} 98 | * @public 99 | */ 100 | 101 | function serialize(name, val, options) { 102 | var opt = options || {}; 103 | var enc = opt.encode || encode; 104 | 105 | if (typeof enc !== 'function') { 106 | throw new TypeError('option encode is invalid'); 107 | } 108 | 109 | if (!fieldContentRegExp.test(name)) { 110 | throw new TypeError('argument name is invalid'); 111 | } 112 | 113 | var value = enc(val); 114 | 115 | if (value && !fieldContentRegExp.test(value)) { 116 | throw new TypeError('argument val is invalid'); 117 | } 118 | 119 | var str = name + '=' + value; 120 | 121 | if (null != opt.maxAge) { 122 | var maxAge = opt.maxAge - 0; 123 | if (isNaN(maxAge)) throw new Error('maxAge should be a Number'); 124 | str += '; Max-Age=' + Math.floor(maxAge); 125 | } 126 | 127 | if (opt.domain) { 128 | if (!fieldContentRegExp.test(opt.domain)) { 129 | throw new TypeError('option domain is invalid'); 130 | } 131 | 132 | str += '; Domain=' + opt.domain; 133 | } 134 | 135 | if (opt.path) { 136 | if (!fieldContentRegExp.test(opt.path)) { 137 | throw new TypeError('option path is invalid'); 138 | } 139 | 140 | str += '; Path=' + opt.path; 141 | } 142 | 143 | if (opt.expires) { 144 | if (typeof opt.expires.toUTCString !== 'function') { 145 | throw new TypeError('option expires is invalid'); 146 | } 147 | 148 | str += '; Expires=' + opt.expires.toUTCString(); 149 | } 150 | 151 | if (opt.httpOnly) { 152 | str += '; HttpOnly'; 153 | } 154 | 155 | if (opt.secure) { 156 | str += '; Secure'; 157 | } 158 | 159 | if (opt.sameSite) { 160 | var sameSite = typeof opt.sameSite === 'string' 161 | ? opt.sameSite.toLowerCase() : opt.sameSite; 162 | 163 | switch (sameSite) { 164 | case true: 165 | str += '; SameSite=Strict'; 166 | break; 167 | case 'lax': 168 | str += '; SameSite=Lax'; 169 | break; 170 | case 'strict': 171 | str += '; SameSite=Strict'; 172 | break; 173 | case 'none': 174 | str += '; SameSite=None'; 175 | break; 176 | default: 177 | throw new TypeError('option sameSite is invalid'); 178 | } 179 | } 180 | 181 | return str; 182 | } 183 | 184 | /** 185 | * Try decoding a string using a decoding function. 186 | * 187 | * @param {string} str 188 | * @param {function} decode 189 | * @private 190 | */ 191 | 192 | function tryDecode(str, decode) { 193 | try { 194 | return decode(str); 195 | } catch (e) { 196 | return str; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/node_modules/cookie/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cookie", 3 | "description": "HTTP server cookie parsing and serialization", 4 | "version": "0.4.0", 5 | "author": "Roman Shtylman ", 6 | "contributors": [ 7 | "Douglas Christopher Wilson " 8 | ], 9 | "license": "MIT", 10 | "keywords": [ 11 | "cookie", 12 | "cookies" 13 | ], 14 | "repository": "jshttp/cookie", 15 | "devDependencies": { 16 | "beautify-benchmark": "0.2.4", 17 | "benchmark": "2.1.4", 18 | "eslint": "5.16.0", 19 | "eslint-plugin-markdown": "1.0.0", 20 | "istanbul": "0.4.5", 21 | "mocha": "6.1.4" 22 | }, 23 | "files": [ 24 | "HISTORY.md", 25 | "LICENSE", 26 | "README.md", 27 | "index.js" 28 | ], 29 | "engines": { 30 | "node": ">= 0.6" 31 | }, 32 | "scripts": { 33 | "bench": "node benchmark/index.js", 34 | "lint": "eslint --plugin markdown --ext js,md .", 35 | "test": "mocha --reporter spec --bail --check-leaks test/", 36 | "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", 37 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", 38 | "version": "node scripts/version-history.js && git add HISTORY.md" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nodejs/node_modules/cookie-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cookie-parser", 3 | "description": "Parse HTTP request cookies", 4 | "version": "1.4.5", 5 | "author": "TJ Holowaychuk (http://tjholowaychuk.com)", 6 | "contributors": [ 7 | "Douglas Christopher Wilson " 8 | ], 9 | "license": "MIT", 10 | "repository": "expressjs/cookie-parser", 11 | "keywords": [ 12 | "cookie", 13 | "middleware" 14 | ], 15 | "dependencies": { 16 | "cookie": "0.4.0", 17 | "cookie-signature": "1.0.6" 18 | }, 19 | "devDependencies": { 20 | "eslint": "6.8.0", 21 | "eslint-config-standard": "14.1.0", 22 | "eslint-plugin-import": "2.20.1", 23 | "eslint-plugin-markdown": "1.0.2", 24 | "eslint-plugin-node": "11.0.0", 25 | "eslint-plugin-promise": "4.2.1", 26 | "eslint-plugin-standard": "4.0.1", 27 | "istanbul": "0.4.5", 28 | "mocha": "7.1.0", 29 | "supertest": "4.0.2" 30 | }, 31 | "files": [ 32 | "LICENSE", 33 | "HISTORY.md", 34 | "index.js" 35 | ], 36 | "engines": { 37 | "node": ">= 0.8.0" 38 | }, 39 | "scripts": { 40 | "lint": "eslint --plugin markdown --ext js,md .", 41 | "test": "mocha --reporter spec --bail --check-leaks test/", 42 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", 43 | "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /nodejs/node_modules/debug/.npmignore: -------------------------------------------------------------------------------- 1 | support 2 | test 3 | examples 4 | example 5 | *.sock 6 | dist 7 | yarn.lock 8 | coverage 9 | bower.json 10 | -------------------------------------------------------------------------------- /nodejs/node_modules/debug/Makefile: -------------------------------------------------------------------------------- 1 | # get Makefile directory name: http://stackoverflow.com/a/5982798/376773 2 | THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) 3 | THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd) 4 | 5 | # BIN directory 6 | BIN := $(THIS_DIR)/node_modules/.bin 7 | 8 | # Path 9 | PATH := node_modules/.bin:$(PATH) 10 | SHELL := /bin/bash 11 | 12 | # applications 13 | NODE ?= $(shell which node) 14 | YARN ?= $(shell which yarn) 15 | PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm)) 16 | BROWSERIFY ?= $(NODE) $(BIN)/browserify 17 | 18 | .FORCE: 19 | 20 | install: node_modules 21 | 22 | node_modules: package.json 23 | @NODE_ENV= $(PKG) install 24 | @touch node_modules 25 | 26 | lint: .FORCE 27 | eslint browser.js debug.js index.js node.js 28 | 29 | test-node: .FORCE 30 | istanbul cover node_modules/mocha/bin/_mocha -- test/**.js 31 | 32 | test-browser: .FORCE 33 | mkdir -p dist 34 | 35 | @$(BROWSERIFY) \ 36 | --standalone debug \ 37 | . > dist/debug.js 38 | 39 | karma start --single-run 40 | rimraf dist 41 | 42 | test: .FORCE 43 | concurrently \ 44 | "make test-node" \ 45 | "make test-browser" 46 | 47 | coveralls: 48 | cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js 49 | 50 | .PHONY: all install clean distclean 51 | -------------------------------------------------------------------------------- /nodejs/node_modules/debug/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "debug", 3 | "repo": "visionmedia/debug", 4 | "description": "small debugging utility", 5 | "version": "2.6.9", 6 | "keywords": [ 7 | "debug", 8 | "log", 9 | "debugger" 10 | ], 11 | "main": "src/browser.js", 12 | "scripts": [ 13 | "src/browser.js", 14 | "src/debug.js" 15 | ], 16 | "dependencies": { 17 | "rauchg/ms.js": "0.7.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /nodejs/node_modules/debug/node.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/node'); 2 | -------------------------------------------------------------------------------- /nodejs/node_modules/debug/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "debug", 3 | "version": "2.6.9", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/visionmedia/debug.git" 7 | }, 8 | "description": "small debugging utility", 9 | "keywords": [ 10 | "debug", 11 | "log", 12 | "debugger" 13 | ], 14 | "author": "TJ Holowaychuk ", 15 | "contributors": [ 16 | "Nathan Rajlich (http://n8.io)", 17 | "Andrew Rhyne " 18 | ], 19 | "license": "MIT", 20 | "dependencies": { 21 | "ms": "2.0.0" 22 | }, 23 | "devDependencies": { 24 | "browserify": "9.0.3", 25 | "chai": "^3.5.0", 26 | "concurrently": "^3.1.0", 27 | "coveralls": "^2.11.15", 28 | "eslint": "^3.12.1", 29 | "istanbul": "^0.4.5", 30 | "karma": "^1.3.0", 31 | "karma-chai": "^0.1.0", 32 | "karma-mocha": "^1.3.0", 33 | "karma-phantomjs-launcher": "^1.0.2", 34 | "karma-sinon": "^1.0.5", 35 | "mocha": "^3.2.0", 36 | "mocha-lcov-reporter": "^1.2.0", 37 | "rimraf": "^2.5.4", 38 | "sinon": "^1.17.6", 39 | "sinon-chai": "^2.8.0" 40 | }, 41 | "main": "./src/index.js", 42 | "browser": "./src/browser.js", 43 | "component": { 44 | "scripts": { 45 | "debug/index.js": "browser.js", 46 | "debug/debug.js": "debug.js" 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2009-2014 TJ Holowaychuk 4 | Copyright (c) 2013-2014 Roman Shtylman 5 | Copyright (c) 2014-2015 Douglas Christopher Wilson 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | 'Software'), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/Readme.md: -------------------------------------------------------------------------------- 1 | [![Express Logo](https://i.cloudup.com/zfY6lL7eFa-3000x3000.png)](http://expressjs.com/) 2 | 3 | Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). 4 | 5 | [![NPM Version][npm-image]][npm-url] 6 | [![NPM Downloads][downloads-image]][downloads-url] 7 | [![Linux Build][travis-image]][travis-url] 8 | [![Windows Build][appveyor-image]][appveyor-url] 9 | [![Test Coverage][coveralls-image]][coveralls-url] 10 | 11 | ```js 12 | var express = require('express') 13 | var app = express() 14 | 15 | app.get('/', function (req, res) { 16 | res.send('Hello World') 17 | }) 18 | 19 | app.listen(3000) 20 | ``` 21 | 22 | ## Installation 23 | 24 | This is a [Node.js](https://nodejs.org/en/) module available through the 25 | [npm registry](https://www.npmjs.com/). 26 | 27 | Before installing, [download and install Node.js](https://nodejs.org/en/download/). 28 | Node.js 0.10 or higher is required. 29 | 30 | Installation is done using the 31 | [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): 32 | 33 | ```bash 34 | $ npm install express 35 | ``` 36 | 37 | Follow [our installing guide](http://expressjs.com/en/starter/installing.html) 38 | for more information. 39 | 40 | ## Features 41 | 42 | * Robust routing 43 | * Focus on high performance 44 | * Super-high test coverage 45 | * HTTP helpers (redirection, caching, etc) 46 | * View system supporting 14+ template engines 47 | * Content negotiation 48 | * Executable for generating applications quickly 49 | 50 | ## Docs & Community 51 | 52 | * [Website and Documentation](http://expressjs.com/) - [[website repo](https://github.com/expressjs/expressjs.com)] 53 | * [#express](https://webchat.freenode.net/?channels=express) on freenode IRC 54 | * [GitHub Organization](https://github.com/expressjs) for Official Middleware & Modules 55 | * Visit the [Wiki](https://github.com/expressjs/express/wiki) 56 | * [Google Group](https://groups.google.com/group/express-js) for discussion 57 | * [Gitter](https://gitter.im/expressjs/express) for support and discussion 58 | 59 | **PROTIP** Be sure to read [Migrating from 3.x to 4.x](https://github.com/expressjs/express/wiki/Migrating-from-3.x-to-4.x) as well as [New features in 4.x](https://github.com/expressjs/express/wiki/New-features-in-4.x). 60 | 61 | ### Security Issues 62 | 63 | If you discover a security vulnerability in Express, please see [Security Policies and Procedures](Security.md). 64 | 65 | ## Quick Start 66 | 67 | The quickest way to get started with express is to utilize the executable [`express(1)`](https://github.com/expressjs/generator) to generate an application as shown below: 68 | 69 | Install the executable. The executable's major version will match Express's: 70 | 71 | ```bash 72 | $ npm install -g express-generator@4 73 | ``` 74 | 75 | Create the app: 76 | 77 | ```bash 78 | $ express /tmp/foo && cd /tmp/foo 79 | ``` 80 | 81 | Install dependencies: 82 | 83 | ```bash 84 | $ npm install 85 | ``` 86 | 87 | Start the server: 88 | 89 | ```bash 90 | $ npm start 91 | ``` 92 | 93 | ## Philosophy 94 | 95 | The Express philosophy is to provide small, robust tooling for HTTP servers, making 96 | it a great solution for single page applications, web sites, hybrids, or public 97 | HTTP APIs. 98 | 99 | Express does not force you to use any specific ORM or template engine. With support for over 100 | 14 template engines via [Consolidate.js](https://github.com/tj/consolidate.js), 101 | you can quickly craft your perfect framework. 102 | 103 | ## Examples 104 | 105 | To view the examples, clone the Express repo and install the dependencies: 106 | 107 | ```bash 108 | $ git clone git://github.com/expressjs/express.git --depth 1 109 | $ cd express 110 | $ npm install 111 | ``` 112 | 113 | Then run whichever example you want: 114 | 115 | ```bash 116 | $ node examples/content-negotiation 117 | ``` 118 | 119 | ## Tests 120 | 121 | To run the test suite, first install the dependencies, then run `npm test`: 122 | 123 | ```bash 124 | $ npm install 125 | $ npm test 126 | ``` 127 | 128 | ## People 129 | 130 | The original author of Express is [TJ Holowaychuk](https://github.com/tj) 131 | 132 | The current lead maintainer is [Douglas Christopher Wilson](https://github.com/dougwilson) 133 | 134 | [List of all contributors](https://github.com/expressjs/express/graphs/contributors) 135 | 136 | ## License 137 | 138 | [MIT](LICENSE) 139 | 140 | [npm-image]: https://img.shields.io/npm/v/express.svg 141 | [npm-url]: https://npmjs.org/package/express 142 | [downloads-image]: https://img.shields.io/npm/dm/express.svg 143 | [downloads-url]: https://npmjs.org/package/express 144 | [travis-image]: https://img.shields.io/travis/expressjs/express/master.svg?label=linux 145 | [travis-url]: https://travis-ci.org/expressjs/express 146 | [appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/express/master.svg?label=windows 147 | [appveyor-url]: https://ci.appveyor.com/project/dougwilson/express 148 | [coveralls-image]: https://img.shields.io/coveralls/expressjs/express/master.svg 149 | [coveralls-url]: https://coveralls.io/r/expressjs/express?branch=master 150 | [gratipay-image-visionmedia]: https://img.shields.io/gratipay/visionmedia.svg 151 | [gratipay-url-visionmedia]: https://gratipay.com/visionmedia/ 152 | [gratipay-image-dougwilson]: https://img.shields.io/gratipay/dougwilson.svg 153 | [gratipay-url-dougwilson]: https://gratipay.com/dougwilson/ 154 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | module.exports = require('./lib/express'); 12 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/application.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var finalhandler = require('finalhandler'); 17 | var Router = require('./router'); 18 | var methods = require('methods'); 19 | var middleware = require('./middleware/init'); 20 | var query = require('./middleware/query'); 21 | var debug = require('debug')('express:application'); 22 | var View = require('./view'); 23 | var http = require('http'); 24 | var compileETag = require('./utils').compileETag; 25 | var compileQueryParser = require('./utils').compileQueryParser; 26 | var compileTrust = require('./utils').compileTrust; 27 | var deprecate = require('depd')('express'); 28 | var flatten = require('array-flatten'); 29 | var merge = require('utils-merge'); 30 | var resolve = require('path').resolve; 31 | var setPrototypeOf = require('setprototypeof') 32 | var slice = Array.prototype.slice; 33 | 34 | /** 35 | * Application prototype. 36 | */ 37 | 38 | var app = exports = module.exports = {}; 39 | 40 | /** 41 | * Variable for trust proxy inheritance back-compat 42 | * @private 43 | */ 44 | 45 | var trustProxyDefaultSymbol = '@@symbol:trust_proxy_default'; 46 | 47 | /** 48 | * Initialize the server. 49 | * 50 | * - setup default configuration 51 | * - setup default middleware 52 | * - setup route reflection methods 53 | * 54 | * @private 55 | */ 56 | 57 | app.init = function init() { 58 | this.cache = {}; 59 | this.engines = {}; 60 | this.settings = {}; 61 | 62 | this.defaultConfiguration(); 63 | }; 64 | 65 | /** 66 | * Initialize application configuration. 67 | * @private 68 | */ 69 | 70 | app.defaultConfiguration = function defaultConfiguration() { 71 | var env = process.env.NODE_ENV || 'development'; 72 | 73 | // default settings 74 | this.enable('x-powered-by'); 75 | this.set('etag', 'weak'); 76 | this.set('env', env); 77 | this.set('query parser', 'extended'); 78 | this.set('subdomain offset', 2); 79 | this.set('trust proxy', false); 80 | 81 | // trust proxy inherit back-compat 82 | Object.defineProperty(this.settings, trustProxyDefaultSymbol, { 83 | configurable: true, 84 | value: true 85 | }); 86 | 87 | debug('booting in %s mode', env); 88 | 89 | this.on('mount', function onmount(parent) { 90 | // inherit trust proxy 91 | if (this.settings[trustProxyDefaultSymbol] === true 92 | && typeof parent.settings['trust proxy fn'] === 'function') { 93 | delete this.settings['trust proxy']; 94 | delete this.settings['trust proxy fn']; 95 | } 96 | 97 | // inherit protos 98 | setPrototypeOf(this.request, parent.request) 99 | setPrototypeOf(this.response, parent.response) 100 | setPrototypeOf(this.engines, parent.engines) 101 | setPrototypeOf(this.settings, parent.settings) 102 | }); 103 | 104 | // setup locals 105 | this.locals = Object.create(null); 106 | 107 | // top-most app is mounted at / 108 | this.mountpath = '/'; 109 | 110 | // default locals 111 | this.locals.settings = this.settings; 112 | 113 | // default configuration 114 | this.set('view', View); 115 | this.set('views', resolve('views')); 116 | this.set('jsonp callback name', 'callback'); 117 | 118 | if (env === 'production') { 119 | this.enable('view cache'); 120 | } 121 | 122 | Object.defineProperty(this, 'router', { 123 | get: function() { 124 | throw new Error('\'app.router\' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app.'); 125 | } 126 | }); 127 | }; 128 | 129 | /** 130 | * lazily adds the base router if it has not yet been added. 131 | * 132 | * We cannot add the base router in the defaultConfiguration because 133 | * it reads app settings which might be set after that has run. 134 | * 135 | * @private 136 | */ 137 | app.lazyrouter = function lazyrouter() { 138 | if (!this._router) { 139 | this._router = new Router({ 140 | caseSensitive: this.enabled('case sensitive routing'), 141 | strict: this.enabled('strict routing') 142 | }); 143 | 144 | this._router.use(query(this.get('query parser fn'))); 145 | this._router.use(middleware.init(this)); 146 | } 147 | }; 148 | 149 | /** 150 | * Dispatch a req, res pair into the application. Starts pipeline processing. 151 | * 152 | * If no callback is provided, then default error handlers will respond 153 | * in the event of an error bubbling through the stack. 154 | * 155 | * @private 156 | */ 157 | 158 | app.handle = function handle(req, res, callback) { 159 | var router = this._router; 160 | 161 | // final handler 162 | var done = callback || finalhandler(req, res, { 163 | env: this.get('env'), 164 | onerror: logerror.bind(this) 165 | }); 166 | 167 | // no routes 168 | if (!router) { 169 | debug('no routes defined on app'); 170 | done(); 171 | return; 172 | } 173 | 174 | router.handle(req, res, done); 175 | }; 176 | 177 | /** 178 | * Proxy `Router#use()` to add middleware to the app router. 179 | * See Router#use() documentation for details. 180 | * 181 | * If the _fn_ parameter is an express app, then it will be 182 | * mounted at the _route_ specified. 183 | * 184 | * @public 185 | */ 186 | 187 | app.use = function use(fn) { 188 | var offset = 0; 189 | var path = '/'; 190 | 191 | // default path to '/' 192 | // disambiguate app.use([fn]) 193 | if (typeof fn !== 'function') { 194 | var arg = fn; 195 | 196 | while (Array.isArray(arg) && arg.length !== 0) { 197 | arg = arg[0]; 198 | } 199 | 200 | // first arg is the path 201 | if (typeof arg !== 'function') { 202 | offset = 1; 203 | path = fn; 204 | } 205 | } 206 | 207 | var fns = flatten(slice.call(arguments, offset)); 208 | 209 | if (fns.length === 0) { 210 | throw new TypeError('app.use() requires a middleware function') 211 | } 212 | 213 | // setup router 214 | this.lazyrouter(); 215 | var router = this._router; 216 | 217 | fns.forEach(function (fn) { 218 | // non-express app 219 | if (!fn || !fn.handle || !fn.set) { 220 | return router.use(path, fn); 221 | } 222 | 223 | debug('.use app under %s', path); 224 | fn.mountpath = path; 225 | fn.parent = this; 226 | 227 | // restore .app property on req and res 228 | router.use(path, function mounted_app(req, res, next) { 229 | var orig = req.app; 230 | fn.handle(req, res, function (err) { 231 | setPrototypeOf(req, orig.request) 232 | setPrototypeOf(res, orig.response) 233 | next(err); 234 | }); 235 | }); 236 | 237 | // mounted an app 238 | fn.emit('mount', this); 239 | }, this); 240 | 241 | return this; 242 | }; 243 | 244 | /** 245 | * Proxy to the app `Router#route()` 246 | * Returns a new `Route` instance for the _path_. 247 | * 248 | * Routes are isolated middleware stacks for specific paths. 249 | * See the Route api docs for details. 250 | * 251 | * @public 252 | */ 253 | 254 | app.route = function route(path) { 255 | this.lazyrouter(); 256 | return this._router.route(path); 257 | }; 258 | 259 | /** 260 | * Register the given template engine callback `fn` 261 | * as `ext`. 262 | * 263 | * By default will `require()` the engine based on the 264 | * file extension. For example if you try to render 265 | * a "foo.ejs" file Express will invoke the following internally: 266 | * 267 | * app.engine('ejs', require('ejs').__express); 268 | * 269 | * For engines that do not provide `.__express` out of the box, 270 | * or if you wish to "map" a different extension to the template engine 271 | * you may use this method. For example mapping the EJS template engine to 272 | * ".html" files: 273 | * 274 | * app.engine('html', require('ejs').renderFile); 275 | * 276 | * In this case EJS provides a `.renderFile()` method with 277 | * the same signature that Express expects: `(path, options, callback)`, 278 | * though note that it aliases this method as `ejs.__express` internally 279 | * so if you're using ".ejs" extensions you dont need to do anything. 280 | * 281 | * Some template engines do not follow this convention, the 282 | * [Consolidate.js](https://github.com/tj/consolidate.js) 283 | * library was created to map all of node's popular template 284 | * engines to follow this convention, thus allowing them to 285 | * work seamlessly within Express. 286 | * 287 | * @param {String} ext 288 | * @param {Function} fn 289 | * @return {app} for chaining 290 | * @public 291 | */ 292 | 293 | app.engine = function engine(ext, fn) { 294 | if (typeof fn !== 'function') { 295 | throw new Error('callback function required'); 296 | } 297 | 298 | // get file extension 299 | var extension = ext[0] !== '.' 300 | ? '.' + ext 301 | : ext; 302 | 303 | // store engine 304 | this.engines[extension] = fn; 305 | 306 | return this; 307 | }; 308 | 309 | /** 310 | * Proxy to `Router#param()` with one added api feature. The _name_ parameter 311 | * can be an array of names. 312 | * 313 | * See the Router#param() docs for more details. 314 | * 315 | * @param {String|Array} name 316 | * @param {Function} fn 317 | * @return {app} for chaining 318 | * @public 319 | */ 320 | 321 | app.param = function param(name, fn) { 322 | this.lazyrouter(); 323 | 324 | if (Array.isArray(name)) { 325 | for (var i = 0; i < name.length; i++) { 326 | this.param(name[i], fn); 327 | } 328 | 329 | return this; 330 | } 331 | 332 | this._router.param(name, fn); 333 | 334 | return this; 335 | }; 336 | 337 | /** 338 | * Assign `setting` to `val`, or return `setting`'s value. 339 | * 340 | * app.set('foo', 'bar'); 341 | * app.set('foo'); 342 | * // => "bar" 343 | * 344 | * Mounted servers inherit their parent server's settings. 345 | * 346 | * @param {String} setting 347 | * @param {*} [val] 348 | * @return {Server} for chaining 349 | * @public 350 | */ 351 | 352 | app.set = function set(setting, val) { 353 | if (arguments.length === 1) { 354 | // app.get(setting) 355 | return this.settings[setting]; 356 | } 357 | 358 | debug('set "%s" to %o', setting, val); 359 | 360 | // set value 361 | this.settings[setting] = val; 362 | 363 | // trigger matched settings 364 | switch (setting) { 365 | case 'etag': 366 | this.set('etag fn', compileETag(val)); 367 | break; 368 | case 'query parser': 369 | this.set('query parser fn', compileQueryParser(val)); 370 | break; 371 | case 'trust proxy': 372 | this.set('trust proxy fn', compileTrust(val)); 373 | 374 | // trust proxy inherit back-compat 375 | Object.defineProperty(this.settings, trustProxyDefaultSymbol, { 376 | configurable: true, 377 | value: false 378 | }); 379 | 380 | break; 381 | } 382 | 383 | return this; 384 | }; 385 | 386 | /** 387 | * Return the app's absolute pathname 388 | * based on the parent(s) that have 389 | * mounted it. 390 | * 391 | * For example if the application was 392 | * mounted as "/admin", which itself 393 | * was mounted as "/blog" then the 394 | * return value would be "/blog/admin". 395 | * 396 | * @return {String} 397 | * @private 398 | */ 399 | 400 | app.path = function path() { 401 | return this.parent 402 | ? this.parent.path() + this.mountpath 403 | : ''; 404 | }; 405 | 406 | /** 407 | * Check if `setting` is enabled (truthy). 408 | * 409 | * app.enabled('foo') 410 | * // => false 411 | * 412 | * app.enable('foo') 413 | * app.enabled('foo') 414 | * // => true 415 | * 416 | * @param {String} setting 417 | * @return {Boolean} 418 | * @public 419 | */ 420 | 421 | app.enabled = function enabled(setting) { 422 | return Boolean(this.set(setting)); 423 | }; 424 | 425 | /** 426 | * Check if `setting` is disabled. 427 | * 428 | * app.disabled('foo') 429 | * // => true 430 | * 431 | * app.enable('foo') 432 | * app.disabled('foo') 433 | * // => false 434 | * 435 | * @param {String} setting 436 | * @return {Boolean} 437 | * @public 438 | */ 439 | 440 | app.disabled = function disabled(setting) { 441 | return !this.set(setting); 442 | }; 443 | 444 | /** 445 | * Enable `setting`. 446 | * 447 | * @param {String} setting 448 | * @return {app} for chaining 449 | * @public 450 | */ 451 | 452 | app.enable = function enable(setting) { 453 | return this.set(setting, true); 454 | }; 455 | 456 | /** 457 | * Disable `setting`. 458 | * 459 | * @param {String} setting 460 | * @return {app} for chaining 461 | * @public 462 | */ 463 | 464 | app.disable = function disable(setting) { 465 | return this.set(setting, false); 466 | }; 467 | 468 | /** 469 | * Delegate `.VERB(...)` calls to `router.VERB(...)`. 470 | */ 471 | 472 | methods.forEach(function(method){ 473 | app[method] = function(path){ 474 | if (method === 'get' && arguments.length === 1) { 475 | // app.get(setting) 476 | return this.set(path); 477 | } 478 | 479 | this.lazyrouter(); 480 | 481 | var route = this._router.route(path); 482 | route[method].apply(route, slice.call(arguments, 1)); 483 | return this; 484 | }; 485 | }); 486 | 487 | /** 488 | * Special-cased "all" method, applying the given route `path`, 489 | * middleware, and callback to _every_ HTTP method. 490 | * 491 | * @param {String} path 492 | * @param {Function} ... 493 | * @return {app} for chaining 494 | * @public 495 | */ 496 | 497 | app.all = function all(path) { 498 | this.lazyrouter(); 499 | 500 | var route = this._router.route(path); 501 | var args = slice.call(arguments, 1); 502 | 503 | for (var i = 0; i < methods.length; i++) { 504 | route[methods[i]].apply(route, args); 505 | } 506 | 507 | return this; 508 | }; 509 | 510 | // del -> delete alias 511 | 512 | app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead'); 513 | 514 | /** 515 | * Render the given view `name` name with `options` 516 | * and a callback accepting an error and the 517 | * rendered template string. 518 | * 519 | * Example: 520 | * 521 | * app.render('email', { name: 'Tobi' }, function(err, html){ 522 | * // ... 523 | * }) 524 | * 525 | * @param {String} name 526 | * @param {Object|Function} options or fn 527 | * @param {Function} callback 528 | * @public 529 | */ 530 | 531 | app.render = function render(name, options, callback) { 532 | var cache = this.cache; 533 | var done = callback; 534 | var engines = this.engines; 535 | var opts = options; 536 | var renderOptions = {}; 537 | var view; 538 | 539 | // support callback function as second arg 540 | if (typeof options === 'function') { 541 | done = options; 542 | opts = {}; 543 | } 544 | 545 | // merge app.locals 546 | merge(renderOptions, this.locals); 547 | 548 | // merge options._locals 549 | if (opts._locals) { 550 | merge(renderOptions, opts._locals); 551 | } 552 | 553 | // merge options 554 | merge(renderOptions, opts); 555 | 556 | // set .cache unless explicitly provided 557 | if (renderOptions.cache == null) { 558 | renderOptions.cache = this.enabled('view cache'); 559 | } 560 | 561 | // primed cache 562 | if (renderOptions.cache) { 563 | view = cache[name]; 564 | } 565 | 566 | // view 567 | if (!view) { 568 | var View = this.get('view'); 569 | 570 | view = new View(name, { 571 | defaultEngine: this.get('view engine'), 572 | root: this.get('views'), 573 | engines: engines 574 | }); 575 | 576 | if (!view.path) { 577 | var dirs = Array.isArray(view.root) && view.root.length > 1 578 | ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' 579 | : 'directory "' + view.root + '"' 580 | var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); 581 | err.view = view; 582 | return done(err); 583 | } 584 | 585 | // prime the cache 586 | if (renderOptions.cache) { 587 | cache[name] = view; 588 | } 589 | } 590 | 591 | // render 592 | tryRender(view, renderOptions, done); 593 | }; 594 | 595 | /** 596 | * Listen for connections. 597 | * 598 | * A node `http.Server` is returned, with this 599 | * application (which is a `Function`) as its 600 | * callback. If you wish to create both an HTTP 601 | * and HTTPS server you may do so with the "http" 602 | * and "https" modules as shown here: 603 | * 604 | * var http = require('http') 605 | * , https = require('https') 606 | * , express = require('express') 607 | * , app = express(); 608 | * 609 | * http.createServer(app).listen(80); 610 | * https.createServer({ ... }, app).listen(443); 611 | * 612 | * @return {http.Server} 613 | * @public 614 | */ 615 | 616 | app.listen = function listen() { 617 | var server = http.createServer(this); 618 | return server.listen.apply(server, arguments); 619 | }; 620 | 621 | /** 622 | * Log error using console.error. 623 | * 624 | * @param {Error} err 625 | * @private 626 | */ 627 | 628 | function logerror(err) { 629 | /* istanbul ignore next */ 630 | if (this.get('env') !== 'test') console.error(err.stack || err.toString()); 631 | } 632 | 633 | /** 634 | * Try rendering a view. 635 | * @private 636 | */ 637 | 638 | function tryRender(view, options, callback) { 639 | try { 640 | view.render(options, callback); 641 | } catch (err) { 642 | callback(err); 643 | } 644 | } 645 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/express.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | */ 14 | 15 | var bodyParser = require('body-parser') 16 | var EventEmitter = require('events').EventEmitter; 17 | var mixin = require('merge-descriptors'); 18 | var proto = require('./application'); 19 | var Route = require('./router/route'); 20 | var Router = require('./router'); 21 | var req = require('./request'); 22 | var res = require('./response'); 23 | 24 | /** 25 | * Expose `createApplication()`. 26 | */ 27 | 28 | exports = module.exports = createApplication; 29 | 30 | /** 31 | * Create an express application. 32 | * 33 | * @return {Function} 34 | * @api public 35 | */ 36 | 37 | function createApplication() { 38 | var app = function(req, res, next) { 39 | app.handle(req, res, next); 40 | }; 41 | 42 | mixin(app, EventEmitter.prototype, false); 43 | mixin(app, proto, false); 44 | 45 | // expose the prototype that will get set on requests 46 | app.request = Object.create(req, { 47 | app: { configurable: true, enumerable: true, writable: true, value: app } 48 | }) 49 | 50 | // expose the prototype that will get set on responses 51 | app.response = Object.create(res, { 52 | app: { configurable: true, enumerable: true, writable: true, value: app } 53 | }) 54 | 55 | app.init(); 56 | return app; 57 | } 58 | 59 | /** 60 | * Expose the prototypes. 61 | */ 62 | 63 | exports.application = proto; 64 | exports.request = req; 65 | exports.response = res; 66 | 67 | /** 68 | * Expose constructors. 69 | */ 70 | 71 | exports.Route = Route; 72 | exports.Router = Router; 73 | 74 | /** 75 | * Expose middleware 76 | */ 77 | 78 | exports.json = bodyParser.json 79 | exports.query = require('./middleware/query'); 80 | exports.static = require('serve-static'); 81 | exports.urlencoded = bodyParser.urlencoded 82 | 83 | /** 84 | * Replace removed middleware with an appropriate error message. 85 | */ 86 | 87 | var removedMiddlewares = [ 88 | 'bodyParser', 89 | 'compress', 90 | 'cookieSession', 91 | 'session', 92 | 'logger', 93 | 'cookieParser', 94 | 'favicon', 95 | 'responseTime', 96 | 'errorHandler', 97 | 'timeout', 98 | 'methodOverride', 99 | 'vhost', 100 | 'csrf', 101 | 'directory', 102 | 'limit', 103 | 'multipart', 104 | 'staticCache' 105 | ] 106 | 107 | removedMiddlewares.forEach(function (name) { 108 | Object.defineProperty(exports, name, { 109 | get: function () { 110 | throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.'); 111 | }, 112 | configurable: true 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/middleware/init.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var setPrototypeOf = require('setprototypeof') 17 | 18 | /** 19 | * Initialization middleware, exposing the 20 | * request and response to each other, as well 21 | * as defaulting the X-Powered-By header field. 22 | * 23 | * @param {Function} app 24 | * @return {Function} 25 | * @api private 26 | */ 27 | 28 | exports.init = function(app){ 29 | return function expressInit(req, res, next){ 30 | if (app.enabled('x-powered-by')) res.setHeader('X-Powered-By', 'Express'); 31 | req.res = res; 32 | res.req = req; 33 | req.next = next; 34 | 35 | setPrototypeOf(req, app.request) 36 | setPrototypeOf(res, app.response) 37 | 38 | res.locals = res.locals || Object.create(null); 39 | 40 | next(); 41 | }; 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/middleware/query.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | */ 14 | 15 | var merge = require('utils-merge') 16 | var parseUrl = require('parseurl'); 17 | var qs = require('qs'); 18 | 19 | /** 20 | * @param {Object} options 21 | * @return {Function} 22 | * @api public 23 | */ 24 | 25 | module.exports = function query(options) { 26 | var opts = merge({}, options) 27 | var queryparse = qs.parse; 28 | 29 | if (typeof options === 'function') { 30 | queryparse = options; 31 | opts = undefined; 32 | } 33 | 34 | if (opts !== undefined && opts.allowPrototypes === undefined) { 35 | // back-compat for qs module 36 | opts.allowPrototypes = true; 37 | } 38 | 39 | return function query(req, res, next){ 40 | if (!req.query) { 41 | var val = parseUrl(req).query; 42 | req.query = queryparse(val, opts); 43 | } 44 | 45 | next(); 46 | }; 47 | }; 48 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/request.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var accepts = require('accepts'); 17 | var deprecate = require('depd')('express'); 18 | var isIP = require('net').isIP; 19 | var typeis = require('type-is'); 20 | var http = require('http'); 21 | var fresh = require('fresh'); 22 | var parseRange = require('range-parser'); 23 | var parse = require('parseurl'); 24 | var proxyaddr = require('proxy-addr'); 25 | 26 | /** 27 | * Request prototype. 28 | * @public 29 | */ 30 | 31 | var req = Object.create(http.IncomingMessage.prototype) 32 | 33 | /** 34 | * Module exports. 35 | * @public 36 | */ 37 | 38 | module.exports = req 39 | 40 | /** 41 | * Return request header. 42 | * 43 | * The `Referrer` header field is special-cased, 44 | * both `Referrer` and `Referer` are interchangeable. 45 | * 46 | * Examples: 47 | * 48 | * req.get('Content-Type'); 49 | * // => "text/plain" 50 | * 51 | * req.get('content-type'); 52 | * // => "text/plain" 53 | * 54 | * req.get('Something'); 55 | * // => undefined 56 | * 57 | * Aliased as `req.header()`. 58 | * 59 | * @param {String} name 60 | * @return {String} 61 | * @public 62 | */ 63 | 64 | req.get = 65 | req.header = function header(name) { 66 | if (!name) { 67 | throw new TypeError('name argument is required to req.get'); 68 | } 69 | 70 | if (typeof name !== 'string') { 71 | throw new TypeError('name must be a string to req.get'); 72 | } 73 | 74 | var lc = name.toLowerCase(); 75 | 76 | switch (lc) { 77 | case 'referer': 78 | case 'referrer': 79 | return this.headers.referrer 80 | || this.headers.referer; 81 | default: 82 | return this.headers[lc]; 83 | } 84 | }; 85 | 86 | /** 87 | * To do: update docs. 88 | * 89 | * Check if the given `type(s)` is acceptable, returning 90 | * the best match when true, otherwise `undefined`, in which 91 | * case you should respond with 406 "Not Acceptable". 92 | * 93 | * The `type` value may be a single MIME type string 94 | * such as "application/json", an extension name 95 | * such as "json", a comma-delimited list such as "json, html, text/plain", 96 | * an argument list such as `"json", "html", "text/plain"`, 97 | * or an array `["json", "html", "text/plain"]`. When a list 98 | * or array is given, the _best_ match, if any is returned. 99 | * 100 | * Examples: 101 | * 102 | * // Accept: text/html 103 | * req.accepts('html'); 104 | * // => "html" 105 | * 106 | * // Accept: text/*, application/json 107 | * req.accepts('html'); 108 | * // => "html" 109 | * req.accepts('text/html'); 110 | * // => "text/html" 111 | * req.accepts('json, text'); 112 | * // => "json" 113 | * req.accepts('application/json'); 114 | * // => "application/json" 115 | * 116 | * // Accept: text/*, application/json 117 | * req.accepts('image/png'); 118 | * req.accepts('png'); 119 | * // => undefined 120 | * 121 | * // Accept: text/*;q=.5, application/json 122 | * req.accepts(['html', 'json']); 123 | * req.accepts('html', 'json'); 124 | * req.accepts('html, json'); 125 | * // => "json" 126 | * 127 | * @param {String|Array} type(s) 128 | * @return {String|Array|Boolean} 129 | * @public 130 | */ 131 | 132 | req.accepts = function(){ 133 | var accept = accepts(this); 134 | return accept.types.apply(accept, arguments); 135 | }; 136 | 137 | /** 138 | * Check if the given `encoding`s are accepted. 139 | * 140 | * @param {String} ...encoding 141 | * @return {String|Array} 142 | * @public 143 | */ 144 | 145 | req.acceptsEncodings = function(){ 146 | var accept = accepts(this); 147 | return accept.encodings.apply(accept, arguments); 148 | }; 149 | 150 | req.acceptsEncoding = deprecate.function(req.acceptsEncodings, 151 | 'req.acceptsEncoding: Use acceptsEncodings instead'); 152 | 153 | /** 154 | * Check if the given `charset`s are acceptable, 155 | * otherwise you should respond with 406 "Not Acceptable". 156 | * 157 | * @param {String} ...charset 158 | * @return {String|Array} 159 | * @public 160 | */ 161 | 162 | req.acceptsCharsets = function(){ 163 | var accept = accepts(this); 164 | return accept.charsets.apply(accept, arguments); 165 | }; 166 | 167 | req.acceptsCharset = deprecate.function(req.acceptsCharsets, 168 | 'req.acceptsCharset: Use acceptsCharsets instead'); 169 | 170 | /** 171 | * Check if the given `lang`s are acceptable, 172 | * otherwise you should respond with 406 "Not Acceptable". 173 | * 174 | * @param {String} ...lang 175 | * @return {String|Array} 176 | * @public 177 | */ 178 | 179 | req.acceptsLanguages = function(){ 180 | var accept = accepts(this); 181 | return accept.languages.apply(accept, arguments); 182 | }; 183 | 184 | req.acceptsLanguage = deprecate.function(req.acceptsLanguages, 185 | 'req.acceptsLanguage: Use acceptsLanguages instead'); 186 | 187 | /** 188 | * Parse Range header field, capping to the given `size`. 189 | * 190 | * Unspecified ranges such as "0-" require knowledge of your resource length. In 191 | * the case of a byte range this is of course the total number of bytes. If the 192 | * Range header field is not given `undefined` is returned, `-1` when unsatisfiable, 193 | * and `-2` when syntactically invalid. 194 | * 195 | * When ranges are returned, the array has a "type" property which is the type of 196 | * range that is required (most commonly, "bytes"). Each array element is an object 197 | * with a "start" and "end" property for the portion of the range. 198 | * 199 | * The "combine" option can be set to `true` and overlapping & adjacent ranges 200 | * will be combined into a single range. 201 | * 202 | * NOTE: remember that ranges are inclusive, so for example "Range: users=0-3" 203 | * should respond with 4 users when available, not 3. 204 | * 205 | * @param {number} size 206 | * @param {object} [options] 207 | * @param {boolean} [options.combine=false] 208 | * @return {number|array} 209 | * @public 210 | */ 211 | 212 | req.range = function range(size, options) { 213 | var range = this.get('Range'); 214 | if (!range) return; 215 | return parseRange(size, range, options); 216 | }; 217 | 218 | /** 219 | * Return the value of param `name` when present or `defaultValue`. 220 | * 221 | * - Checks route placeholders, ex: _/user/:id_ 222 | * - Checks body params, ex: id=12, {"id":12} 223 | * - Checks query string params, ex: ?id=12 224 | * 225 | * To utilize request bodies, `req.body` 226 | * should be an object. This can be done by using 227 | * the `bodyParser()` middleware. 228 | * 229 | * @param {String} name 230 | * @param {Mixed} [defaultValue] 231 | * @return {String} 232 | * @public 233 | */ 234 | 235 | req.param = function param(name, defaultValue) { 236 | var params = this.params || {}; 237 | var body = this.body || {}; 238 | var query = this.query || {}; 239 | 240 | var args = arguments.length === 1 241 | ? 'name' 242 | : 'name, default'; 243 | deprecate('req.param(' + args + '): Use req.params, req.body, or req.query instead'); 244 | 245 | if (null != params[name] && params.hasOwnProperty(name)) return params[name]; 246 | if (null != body[name]) return body[name]; 247 | if (null != query[name]) return query[name]; 248 | 249 | return defaultValue; 250 | }; 251 | 252 | /** 253 | * Check if the incoming request contains the "Content-Type" 254 | * header field, and it contains the give mime `type`. 255 | * 256 | * Examples: 257 | * 258 | * // With Content-Type: text/html; charset=utf-8 259 | * req.is('html'); 260 | * req.is('text/html'); 261 | * req.is('text/*'); 262 | * // => true 263 | * 264 | * // When Content-Type is application/json 265 | * req.is('json'); 266 | * req.is('application/json'); 267 | * req.is('application/*'); 268 | * // => true 269 | * 270 | * req.is('html'); 271 | * // => false 272 | * 273 | * @param {String|Array} types... 274 | * @return {String|false|null} 275 | * @public 276 | */ 277 | 278 | req.is = function is(types) { 279 | var arr = types; 280 | 281 | // support flattened arguments 282 | if (!Array.isArray(types)) { 283 | arr = new Array(arguments.length); 284 | for (var i = 0; i < arr.length; i++) { 285 | arr[i] = arguments[i]; 286 | } 287 | } 288 | 289 | return typeis(this, arr); 290 | }; 291 | 292 | /** 293 | * Return the protocol string "http" or "https" 294 | * when requested with TLS. When the "trust proxy" 295 | * setting trusts the socket address, the 296 | * "X-Forwarded-Proto" header field will be trusted 297 | * and used if present. 298 | * 299 | * If you're running behind a reverse proxy that 300 | * supplies https for you this may be enabled. 301 | * 302 | * @return {String} 303 | * @public 304 | */ 305 | 306 | defineGetter(req, 'protocol', function protocol(){ 307 | var proto = this.connection.encrypted 308 | ? 'https' 309 | : 'http'; 310 | var trust = this.app.get('trust proxy fn'); 311 | 312 | if (!trust(this.connection.remoteAddress, 0)) { 313 | return proto; 314 | } 315 | 316 | // Note: X-Forwarded-Proto is normally only ever a 317 | // single value, but this is to be safe. 318 | var header = this.get('X-Forwarded-Proto') || proto 319 | var index = header.indexOf(',') 320 | 321 | return index !== -1 322 | ? header.substring(0, index).trim() 323 | : header.trim() 324 | }); 325 | 326 | /** 327 | * Short-hand for: 328 | * 329 | * req.protocol === 'https' 330 | * 331 | * @return {Boolean} 332 | * @public 333 | */ 334 | 335 | defineGetter(req, 'secure', function secure(){ 336 | return this.protocol === 'https'; 337 | }); 338 | 339 | /** 340 | * Return the remote address from the trusted proxy. 341 | * 342 | * The is the remote address on the socket unless 343 | * "trust proxy" is set. 344 | * 345 | * @return {String} 346 | * @public 347 | */ 348 | 349 | defineGetter(req, 'ip', function ip(){ 350 | var trust = this.app.get('trust proxy fn'); 351 | return proxyaddr(this, trust); 352 | }); 353 | 354 | /** 355 | * When "trust proxy" is set, trusted proxy addresses + client. 356 | * 357 | * For example if the value were "client, proxy1, proxy2" 358 | * you would receive the array `["client", "proxy1", "proxy2"]` 359 | * where "proxy2" is the furthest down-stream and "proxy1" and 360 | * "proxy2" were trusted. 361 | * 362 | * @return {Array} 363 | * @public 364 | */ 365 | 366 | defineGetter(req, 'ips', function ips() { 367 | var trust = this.app.get('trust proxy fn'); 368 | var addrs = proxyaddr.all(this, trust); 369 | 370 | // reverse the order (to farthest -> closest) 371 | // and remove socket address 372 | addrs.reverse().pop() 373 | 374 | return addrs 375 | }); 376 | 377 | /** 378 | * Return subdomains as an array. 379 | * 380 | * Subdomains are the dot-separated parts of the host before the main domain of 381 | * the app. By default, the domain of the app is assumed to be the last two 382 | * parts of the host. This can be changed by setting "subdomain offset". 383 | * 384 | * For example, if the domain is "tobi.ferrets.example.com": 385 | * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`. 386 | * If "subdomain offset" is 3, req.subdomains is `["tobi"]`. 387 | * 388 | * @return {Array} 389 | * @public 390 | */ 391 | 392 | defineGetter(req, 'subdomains', function subdomains() { 393 | var hostname = this.hostname; 394 | 395 | if (!hostname) return []; 396 | 397 | var offset = this.app.get('subdomain offset'); 398 | var subdomains = !isIP(hostname) 399 | ? hostname.split('.').reverse() 400 | : [hostname]; 401 | 402 | return subdomains.slice(offset); 403 | }); 404 | 405 | /** 406 | * Short-hand for `url.parse(req.url).pathname`. 407 | * 408 | * @return {String} 409 | * @public 410 | */ 411 | 412 | defineGetter(req, 'path', function path() { 413 | return parse(this).pathname; 414 | }); 415 | 416 | /** 417 | * Parse the "Host" header field to a hostname. 418 | * 419 | * When the "trust proxy" setting trusts the socket 420 | * address, the "X-Forwarded-Host" header field will 421 | * be trusted. 422 | * 423 | * @return {String} 424 | * @public 425 | */ 426 | 427 | defineGetter(req, 'hostname', function hostname(){ 428 | var trust = this.app.get('trust proxy fn'); 429 | var host = this.get('X-Forwarded-Host'); 430 | 431 | if (!host || !trust(this.connection.remoteAddress, 0)) { 432 | host = this.get('Host'); 433 | } 434 | 435 | if (!host) return; 436 | 437 | // IPv6 literal support 438 | var offset = host[0] === '[' 439 | ? host.indexOf(']') + 1 440 | : 0; 441 | var index = host.indexOf(':', offset); 442 | 443 | return index !== -1 444 | ? host.substring(0, index) 445 | : host; 446 | }); 447 | 448 | // TODO: change req.host to return host in next major 449 | 450 | defineGetter(req, 'host', deprecate.function(function host(){ 451 | return this.hostname; 452 | }, 'req.host: Use req.hostname instead')); 453 | 454 | /** 455 | * Check if the request is fresh, aka 456 | * Last-Modified and/or the ETag 457 | * still match. 458 | * 459 | * @return {Boolean} 460 | * @public 461 | */ 462 | 463 | defineGetter(req, 'fresh', function(){ 464 | var method = this.method; 465 | var res = this.res 466 | var status = res.statusCode 467 | 468 | // GET or HEAD for weak freshness validation only 469 | if ('GET' !== method && 'HEAD' !== method) return false; 470 | 471 | // 2xx or 304 as per rfc2616 14.26 472 | if ((status >= 200 && status < 300) || 304 === status) { 473 | return fresh(this.headers, { 474 | 'etag': res.get('ETag'), 475 | 'last-modified': res.get('Last-Modified') 476 | }) 477 | } 478 | 479 | return false; 480 | }); 481 | 482 | /** 483 | * Check if the request is stale, aka 484 | * "Last-Modified" and / or the "ETag" for the 485 | * resource has changed. 486 | * 487 | * @return {Boolean} 488 | * @public 489 | */ 490 | 491 | defineGetter(req, 'stale', function stale(){ 492 | return !this.fresh; 493 | }); 494 | 495 | /** 496 | * Check if the request was an _XMLHttpRequest_. 497 | * 498 | * @return {Boolean} 499 | * @public 500 | */ 501 | 502 | defineGetter(req, 'xhr', function xhr(){ 503 | var val = this.get('X-Requested-With') || ''; 504 | return val.toLowerCase() === 'xmlhttprequest'; 505 | }); 506 | 507 | /** 508 | * Helper function for creating a getter on an object. 509 | * 510 | * @param {Object} obj 511 | * @param {String} name 512 | * @param {Function} getter 513 | * @private 514 | */ 515 | function defineGetter(obj, name, getter) { 516 | Object.defineProperty(obj, name, { 517 | configurable: true, 518 | enumerable: true, 519 | get: getter 520 | }); 521 | } 522 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/router/layer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var pathRegexp = require('path-to-regexp'); 17 | var debug = require('debug')('express:router:layer'); 18 | 19 | /** 20 | * Module variables. 21 | * @private 22 | */ 23 | 24 | var hasOwnProperty = Object.prototype.hasOwnProperty; 25 | 26 | /** 27 | * Module exports. 28 | * @public 29 | */ 30 | 31 | module.exports = Layer; 32 | 33 | function Layer(path, options, fn) { 34 | if (!(this instanceof Layer)) { 35 | return new Layer(path, options, fn); 36 | } 37 | 38 | debug('new %o', path) 39 | var opts = options || {}; 40 | 41 | this.handle = fn; 42 | this.name = fn.name || ''; 43 | this.params = undefined; 44 | this.path = undefined; 45 | this.regexp = pathRegexp(path, this.keys = [], opts); 46 | 47 | // set fast path flags 48 | this.regexp.fast_star = path === '*' 49 | this.regexp.fast_slash = path === '/' && opts.end === false 50 | } 51 | 52 | /** 53 | * Handle the error for the layer. 54 | * 55 | * @param {Error} error 56 | * @param {Request} req 57 | * @param {Response} res 58 | * @param {function} next 59 | * @api private 60 | */ 61 | 62 | Layer.prototype.handle_error = function handle_error(error, req, res, next) { 63 | var fn = this.handle; 64 | 65 | if (fn.length !== 4) { 66 | // not a standard error handler 67 | return next(error); 68 | } 69 | 70 | try { 71 | fn(error, req, res, next); 72 | } catch (err) { 73 | next(err); 74 | } 75 | }; 76 | 77 | /** 78 | * Handle the request for the layer. 79 | * 80 | * @param {Request} req 81 | * @param {Response} res 82 | * @param {function} next 83 | * @api private 84 | */ 85 | 86 | Layer.prototype.handle_request = function handle(req, res, next) { 87 | var fn = this.handle; 88 | 89 | if (fn.length > 3) { 90 | // not a standard request handler 91 | return next(); 92 | } 93 | 94 | try { 95 | fn(req, res, next); 96 | } catch (err) { 97 | next(err); 98 | } 99 | }; 100 | 101 | /** 102 | * Check if this route matches `path`, if so 103 | * populate `.params`. 104 | * 105 | * @param {String} path 106 | * @return {Boolean} 107 | * @api private 108 | */ 109 | 110 | Layer.prototype.match = function match(path) { 111 | var match 112 | 113 | if (path != null) { 114 | // fast path non-ending match for / (any path matches) 115 | if (this.regexp.fast_slash) { 116 | this.params = {} 117 | this.path = '' 118 | return true 119 | } 120 | 121 | // fast path for * (everything matched in a param) 122 | if (this.regexp.fast_star) { 123 | this.params = {'0': decode_param(path)} 124 | this.path = path 125 | return true 126 | } 127 | 128 | // match the path 129 | match = this.regexp.exec(path) 130 | } 131 | 132 | if (!match) { 133 | this.params = undefined; 134 | this.path = undefined; 135 | return false; 136 | } 137 | 138 | // store values 139 | this.params = {}; 140 | this.path = match[0] 141 | 142 | var keys = this.keys; 143 | var params = this.params; 144 | 145 | for (var i = 1; i < match.length; i++) { 146 | var key = keys[i - 1]; 147 | var prop = key.name; 148 | var val = decode_param(match[i]) 149 | 150 | if (val !== undefined || !(hasOwnProperty.call(params, prop))) { 151 | params[prop] = val; 152 | } 153 | } 154 | 155 | return true; 156 | }; 157 | 158 | /** 159 | * Decode param value. 160 | * 161 | * @param {string} val 162 | * @return {string} 163 | * @private 164 | */ 165 | 166 | function decode_param(val) { 167 | if (typeof val !== 'string' || val.length === 0) { 168 | return val; 169 | } 170 | 171 | try { 172 | return decodeURIComponent(val); 173 | } catch (err) { 174 | if (err instanceof URIError) { 175 | err.message = 'Failed to decode param \'' + val + '\''; 176 | err.status = err.statusCode = 400; 177 | } 178 | 179 | throw err; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/router/route.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var debug = require('debug')('express:router:route'); 17 | var flatten = require('array-flatten'); 18 | var Layer = require('./layer'); 19 | var methods = require('methods'); 20 | 21 | /** 22 | * Module variables. 23 | * @private 24 | */ 25 | 26 | var slice = Array.prototype.slice; 27 | var toString = Object.prototype.toString; 28 | 29 | /** 30 | * Module exports. 31 | * @public 32 | */ 33 | 34 | module.exports = Route; 35 | 36 | /** 37 | * Initialize `Route` with the given `path`, 38 | * 39 | * @param {String} path 40 | * @public 41 | */ 42 | 43 | function Route(path) { 44 | this.path = path; 45 | this.stack = []; 46 | 47 | debug('new %o', path) 48 | 49 | // route handlers for various http methods 50 | this.methods = {}; 51 | } 52 | 53 | /** 54 | * Determine if the route handles a given method. 55 | * @private 56 | */ 57 | 58 | Route.prototype._handles_method = function _handles_method(method) { 59 | if (this.methods._all) { 60 | return true; 61 | } 62 | 63 | var name = method.toLowerCase(); 64 | 65 | if (name === 'head' && !this.methods['head']) { 66 | name = 'get'; 67 | } 68 | 69 | return Boolean(this.methods[name]); 70 | }; 71 | 72 | /** 73 | * @return {Array} supported HTTP methods 74 | * @private 75 | */ 76 | 77 | Route.prototype._options = function _options() { 78 | var methods = Object.keys(this.methods); 79 | 80 | // append automatic head 81 | if (this.methods.get && !this.methods.head) { 82 | methods.push('head'); 83 | } 84 | 85 | for (var i = 0; i < methods.length; i++) { 86 | // make upper case 87 | methods[i] = methods[i].toUpperCase(); 88 | } 89 | 90 | return methods; 91 | }; 92 | 93 | /** 94 | * dispatch req, res into this route 95 | * @private 96 | */ 97 | 98 | Route.prototype.dispatch = function dispatch(req, res, done) { 99 | var idx = 0; 100 | var stack = this.stack; 101 | if (stack.length === 0) { 102 | return done(); 103 | } 104 | 105 | var method = req.method.toLowerCase(); 106 | if (method === 'head' && !this.methods['head']) { 107 | method = 'get'; 108 | } 109 | 110 | req.route = this; 111 | 112 | next(); 113 | 114 | function next(err) { 115 | // signal to exit route 116 | if (err && err === 'route') { 117 | return done(); 118 | } 119 | 120 | // signal to exit router 121 | if (err && err === 'router') { 122 | return done(err) 123 | } 124 | 125 | var layer = stack[idx++]; 126 | if (!layer) { 127 | return done(err); 128 | } 129 | 130 | if (layer.method && layer.method !== method) { 131 | return next(err); 132 | } 133 | 134 | if (err) { 135 | layer.handle_error(err, req, res, next); 136 | } else { 137 | layer.handle_request(req, res, next); 138 | } 139 | } 140 | }; 141 | 142 | /** 143 | * Add a handler for all HTTP verbs to this route. 144 | * 145 | * Behaves just like middleware and can respond or call `next` 146 | * to continue processing. 147 | * 148 | * You can use multiple `.all` call to add multiple handlers. 149 | * 150 | * function check_something(req, res, next){ 151 | * next(); 152 | * }; 153 | * 154 | * function validate_user(req, res, next){ 155 | * next(); 156 | * }; 157 | * 158 | * route 159 | * .all(validate_user) 160 | * .all(check_something) 161 | * .get(function(req, res, next){ 162 | * res.send('hello world'); 163 | * }); 164 | * 165 | * @param {function} handler 166 | * @return {Route} for chaining 167 | * @api public 168 | */ 169 | 170 | Route.prototype.all = function all() { 171 | var handles = flatten(slice.call(arguments)); 172 | 173 | for (var i = 0; i < handles.length; i++) { 174 | var handle = handles[i]; 175 | 176 | if (typeof handle !== 'function') { 177 | var type = toString.call(handle); 178 | var msg = 'Route.all() requires a callback function but got a ' + type 179 | throw new TypeError(msg); 180 | } 181 | 182 | var layer = Layer('/', {}, handle); 183 | layer.method = undefined; 184 | 185 | this.methods._all = true; 186 | this.stack.push(layer); 187 | } 188 | 189 | return this; 190 | }; 191 | 192 | methods.forEach(function(method){ 193 | Route.prototype[method] = function(){ 194 | var handles = flatten(slice.call(arguments)); 195 | 196 | for (var i = 0; i < handles.length; i++) { 197 | var handle = handles[i]; 198 | 199 | if (typeof handle !== 'function') { 200 | var type = toString.call(handle); 201 | var msg = 'Route.' + method + '() requires a callback function but got a ' + type 202 | throw new Error(msg); 203 | } 204 | 205 | debug('%s %o', method, this.path) 206 | 207 | var layer = Layer('/', {}, handle); 208 | layer.method = method; 209 | 210 | this.methods[method] = true; 211 | this.stack.push(layer); 212 | } 213 | 214 | return this; 215 | }; 216 | }); 217 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/utils.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 5 | * MIT Licensed 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * Module dependencies. 12 | * @api private 13 | */ 14 | 15 | var Buffer = require('safe-buffer').Buffer 16 | var contentDisposition = require('content-disposition'); 17 | var contentType = require('content-type'); 18 | var deprecate = require('depd')('express'); 19 | var flatten = require('array-flatten'); 20 | var mime = require('send').mime; 21 | var etag = require('etag'); 22 | var proxyaddr = require('proxy-addr'); 23 | var qs = require('qs'); 24 | var querystring = require('querystring'); 25 | 26 | /** 27 | * Return strong ETag for `body`. 28 | * 29 | * @param {String|Buffer} body 30 | * @param {String} [encoding] 31 | * @return {String} 32 | * @api private 33 | */ 34 | 35 | exports.etag = createETagGenerator({ weak: false }) 36 | 37 | /** 38 | * Return weak ETag for `body`. 39 | * 40 | * @param {String|Buffer} body 41 | * @param {String} [encoding] 42 | * @return {String} 43 | * @api private 44 | */ 45 | 46 | exports.wetag = createETagGenerator({ weak: true }) 47 | 48 | /** 49 | * Check if `path` looks absolute. 50 | * 51 | * @param {String} path 52 | * @return {Boolean} 53 | * @api private 54 | */ 55 | 56 | exports.isAbsolute = function(path){ 57 | if ('/' === path[0]) return true; 58 | if (':' === path[1] && ('\\' === path[2] || '/' === path[2])) return true; // Windows device path 59 | if ('\\\\' === path.substring(0, 2)) return true; // Microsoft Azure absolute path 60 | }; 61 | 62 | /** 63 | * Flatten the given `arr`. 64 | * 65 | * @param {Array} arr 66 | * @return {Array} 67 | * @api private 68 | */ 69 | 70 | exports.flatten = deprecate.function(flatten, 71 | 'utils.flatten: use array-flatten npm module instead'); 72 | 73 | /** 74 | * Normalize the given `type`, for example "html" becomes "text/html". 75 | * 76 | * @param {String} type 77 | * @return {Object} 78 | * @api private 79 | */ 80 | 81 | exports.normalizeType = function(type){ 82 | return ~type.indexOf('/') 83 | ? acceptParams(type) 84 | : { value: mime.lookup(type), params: {} }; 85 | }; 86 | 87 | /** 88 | * Normalize `types`, for example "html" becomes "text/html". 89 | * 90 | * @param {Array} types 91 | * @return {Array} 92 | * @api private 93 | */ 94 | 95 | exports.normalizeTypes = function(types){ 96 | var ret = []; 97 | 98 | for (var i = 0; i < types.length; ++i) { 99 | ret.push(exports.normalizeType(types[i])); 100 | } 101 | 102 | return ret; 103 | }; 104 | 105 | /** 106 | * Generate Content-Disposition header appropriate for the filename. 107 | * non-ascii filenames are urlencoded and a filename* parameter is added 108 | * 109 | * @param {String} filename 110 | * @return {String} 111 | * @api private 112 | */ 113 | 114 | exports.contentDisposition = deprecate.function(contentDisposition, 115 | 'utils.contentDisposition: use content-disposition npm module instead'); 116 | 117 | /** 118 | * Parse accept params `str` returning an 119 | * object with `.value`, `.quality` and `.params`. 120 | * also includes `.originalIndex` for stable sorting 121 | * 122 | * @param {String} str 123 | * @return {Object} 124 | * @api private 125 | */ 126 | 127 | function acceptParams(str, index) { 128 | var parts = str.split(/ *; */); 129 | var ret = { value: parts[0], quality: 1, params: {}, originalIndex: index }; 130 | 131 | for (var i = 1; i < parts.length; ++i) { 132 | var pms = parts[i].split(/ *= */); 133 | if ('q' === pms[0]) { 134 | ret.quality = parseFloat(pms[1]); 135 | } else { 136 | ret.params[pms[0]] = pms[1]; 137 | } 138 | } 139 | 140 | return ret; 141 | } 142 | 143 | /** 144 | * Compile "etag" value to function. 145 | * 146 | * @param {Boolean|String|Function} val 147 | * @return {Function} 148 | * @api private 149 | */ 150 | 151 | exports.compileETag = function(val) { 152 | var fn; 153 | 154 | if (typeof val === 'function') { 155 | return val; 156 | } 157 | 158 | switch (val) { 159 | case true: 160 | fn = exports.wetag; 161 | break; 162 | case false: 163 | break; 164 | case 'strong': 165 | fn = exports.etag; 166 | break; 167 | case 'weak': 168 | fn = exports.wetag; 169 | break; 170 | default: 171 | throw new TypeError('unknown value for etag function: ' + val); 172 | } 173 | 174 | return fn; 175 | } 176 | 177 | /** 178 | * Compile "query parser" value to function. 179 | * 180 | * @param {String|Function} val 181 | * @return {Function} 182 | * @api private 183 | */ 184 | 185 | exports.compileQueryParser = function compileQueryParser(val) { 186 | var fn; 187 | 188 | if (typeof val === 'function') { 189 | return val; 190 | } 191 | 192 | switch (val) { 193 | case true: 194 | fn = querystring.parse; 195 | break; 196 | case false: 197 | fn = newObject; 198 | break; 199 | case 'extended': 200 | fn = parseExtendedQueryString; 201 | break; 202 | case 'simple': 203 | fn = querystring.parse; 204 | break; 205 | default: 206 | throw new TypeError('unknown value for query parser function: ' + val); 207 | } 208 | 209 | return fn; 210 | } 211 | 212 | /** 213 | * Compile "proxy trust" value to function. 214 | * 215 | * @param {Boolean|String|Number|Array|Function} val 216 | * @return {Function} 217 | * @api private 218 | */ 219 | 220 | exports.compileTrust = function(val) { 221 | if (typeof val === 'function') return val; 222 | 223 | if (val === true) { 224 | // Support plain true/false 225 | return function(){ return true }; 226 | } 227 | 228 | if (typeof val === 'number') { 229 | // Support trusting hop count 230 | return function(a, i){ return i < val }; 231 | } 232 | 233 | if (typeof val === 'string') { 234 | // Support comma-separated values 235 | val = val.split(/ *, */); 236 | } 237 | 238 | return proxyaddr.compile(val || []); 239 | } 240 | 241 | /** 242 | * Set the charset in a given Content-Type string. 243 | * 244 | * @param {String} type 245 | * @param {String} charset 246 | * @return {String} 247 | * @api private 248 | */ 249 | 250 | exports.setCharset = function setCharset(type, charset) { 251 | if (!type || !charset) { 252 | return type; 253 | } 254 | 255 | // parse type 256 | var parsed = contentType.parse(type); 257 | 258 | // set charset 259 | parsed.parameters.charset = charset; 260 | 261 | // format type 262 | return contentType.format(parsed); 263 | }; 264 | 265 | /** 266 | * Create an ETag generator function, generating ETags with 267 | * the given options. 268 | * 269 | * @param {object} options 270 | * @return {function} 271 | * @private 272 | */ 273 | 274 | function createETagGenerator (options) { 275 | return function generateETag (body, encoding) { 276 | var buf = !Buffer.isBuffer(body) 277 | ? Buffer.from(body, encoding) 278 | : body 279 | 280 | return etag(buf, options) 281 | } 282 | } 283 | 284 | /** 285 | * Parse an extended query string with qs. 286 | * 287 | * @return {Object} 288 | * @private 289 | */ 290 | 291 | function parseExtendedQueryString(str) { 292 | return qs.parse(str, { 293 | allowPrototypes: true 294 | }); 295 | } 296 | 297 | /** 298 | * Return new empty object. 299 | * 300 | * @return {Object} 301 | * @api private 302 | */ 303 | 304 | function newObject() { 305 | return {}; 306 | } 307 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/lib/view.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * express 3 | * Copyright(c) 2009-2013 TJ Holowaychuk 4 | * Copyright(c) 2013 Roman Shtylman 5 | * Copyright(c) 2014-2015 Douglas Christopher Wilson 6 | * MIT Licensed 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Module dependencies. 13 | * @private 14 | */ 15 | 16 | var debug = require('debug')('express:view'); 17 | var path = require('path'); 18 | var fs = require('fs'); 19 | 20 | /** 21 | * Module variables. 22 | * @private 23 | */ 24 | 25 | var dirname = path.dirname; 26 | var basename = path.basename; 27 | var extname = path.extname; 28 | var join = path.join; 29 | var resolve = path.resolve; 30 | 31 | /** 32 | * Module exports. 33 | * @public 34 | */ 35 | 36 | module.exports = View; 37 | 38 | /** 39 | * Initialize a new `View` with the given `name`. 40 | * 41 | * Options: 42 | * 43 | * - `defaultEngine` the default template engine name 44 | * - `engines` template engine require() cache 45 | * - `root` root path for view lookup 46 | * 47 | * @param {string} name 48 | * @param {object} options 49 | * @public 50 | */ 51 | 52 | function View(name, options) { 53 | var opts = options || {}; 54 | 55 | this.defaultEngine = opts.defaultEngine; 56 | this.ext = extname(name); 57 | this.name = name; 58 | this.root = opts.root; 59 | 60 | if (!this.ext && !this.defaultEngine) { 61 | throw new Error('No default engine was specified and no extension was provided.'); 62 | } 63 | 64 | var fileName = name; 65 | 66 | if (!this.ext) { 67 | // get extension from default engine name 68 | this.ext = this.defaultEngine[0] !== '.' 69 | ? '.' + this.defaultEngine 70 | : this.defaultEngine; 71 | 72 | fileName += this.ext; 73 | } 74 | 75 | if (!opts.engines[this.ext]) { 76 | // load engine 77 | var mod = this.ext.substr(1) 78 | debug('require "%s"', mod) 79 | 80 | // default engine export 81 | var fn = require(mod).__express 82 | 83 | if (typeof fn !== 'function') { 84 | throw new Error('Module "' + mod + '" does not provide a view engine.') 85 | } 86 | 87 | opts.engines[this.ext] = fn 88 | } 89 | 90 | // store loaded engine 91 | this.engine = opts.engines[this.ext]; 92 | 93 | // lookup path 94 | this.path = this.lookup(fileName); 95 | } 96 | 97 | /** 98 | * Lookup view by the given `name` 99 | * 100 | * @param {string} name 101 | * @private 102 | */ 103 | 104 | View.prototype.lookup = function lookup(name) { 105 | var path; 106 | var roots = [].concat(this.root); 107 | 108 | debug('lookup "%s"', name); 109 | 110 | for (var i = 0; i < roots.length && !path; i++) { 111 | var root = roots[i]; 112 | 113 | // resolve the path 114 | var loc = resolve(root, name); 115 | var dir = dirname(loc); 116 | var file = basename(loc); 117 | 118 | // resolve the file 119 | path = this.resolve(dir, file); 120 | } 121 | 122 | return path; 123 | }; 124 | 125 | /** 126 | * Render with the given options. 127 | * 128 | * @param {object} options 129 | * @param {function} callback 130 | * @private 131 | */ 132 | 133 | View.prototype.render = function render(options, callback) { 134 | debug('render "%s"', this.path); 135 | this.engine(this.path, options, callback); 136 | }; 137 | 138 | /** 139 | * Resolve the file within the given directory. 140 | * 141 | * @param {string} dir 142 | * @param {string} file 143 | * @private 144 | */ 145 | 146 | View.prototype.resolve = function resolve(dir, file) { 147 | var ext = this.ext; 148 | 149 | // . 150 | var path = join(dir, file); 151 | var stat = tryStat(path); 152 | 153 | if (stat && stat.isFile()) { 154 | return path; 155 | } 156 | 157 | // /index. 158 | path = join(dir, basename(file, ext), 'index' + ext); 159 | stat = tryStat(path); 160 | 161 | if (stat && stat.isFile()) { 162 | return path; 163 | } 164 | }; 165 | 166 | /** 167 | * Return a stat, maybe. 168 | * 169 | * @param {string} path 170 | * @return {fs.Stats} 171 | * @private 172 | */ 173 | 174 | function tryStat(path) { 175 | debug('stat "%s"', path); 176 | 177 | try { 178 | return fs.statSync(path); 179 | } catch (e) { 180 | return undefined; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /nodejs/node_modules/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express", 3 | "description": "Fast, unopinionated, minimalist web framework", 4 | "version": "4.16.4", 5 | "author": "TJ Holowaychuk ", 6 | "contributors": [ 7 | "Aaron Heckmann ", 8 | "Ciaran Jessup ", 9 | "Douglas Christopher Wilson ", 10 | "Guillermo Rauch ", 11 | "Jonathan Ong ", 12 | "Roman Shtylman ", 13 | "Young Jae Sim " 14 | ], 15 | "license": "MIT", 16 | "repository": "expressjs/express", 17 | "homepage": "http://expressjs.com/", 18 | "keywords": [ 19 | "express", 20 | "framework", 21 | "sinatra", 22 | "web", 23 | "rest", 24 | "restful", 25 | "router", 26 | "app", 27 | "api" 28 | ], 29 | "dependencies": { 30 | "accepts": "~1.3.5", 31 | "array-flatten": "1.1.1", 32 | "body-parser": "1.18.3", 33 | "content-disposition": "0.5.2", 34 | "content-type": "~1.0.4", 35 | "cookie": "0.3.1", 36 | "cookie-signature": "1.0.6", 37 | "debug": "2.6.9", 38 | "depd": "~1.1.2", 39 | "encodeurl": "~1.0.2", 40 | "escape-html": "~1.0.3", 41 | "etag": "~1.8.1", 42 | "finalhandler": "1.1.1", 43 | "fresh": "0.5.2", 44 | "merge-descriptors": "1.0.1", 45 | "methods": "~1.1.2", 46 | "on-finished": "~2.3.0", 47 | "parseurl": "~1.3.2", 48 | "path-to-regexp": "0.1.7", 49 | "proxy-addr": "~2.0.4", 50 | "qs": "6.5.2", 51 | "range-parser": "~1.2.0", 52 | "safe-buffer": "5.1.2", 53 | "send": "0.16.2", 54 | "serve-static": "1.13.2", 55 | "setprototypeof": "1.1.0", 56 | "statuses": "~1.4.0", 57 | "type-is": "~1.6.16", 58 | "utils-merge": "1.0.1", 59 | "vary": "~1.1.2" 60 | }, 61 | "devDependencies": { 62 | "after": "0.8.2", 63 | "connect-redis": "3.4.0", 64 | "cookie-parser": "~1.4.3", 65 | "cookie-session": "1.3.2", 66 | "ejs": "2.6.1", 67 | "eslint": "2.13.1", 68 | "express-session": "1.15.6", 69 | "hbs": "4.0.1", 70 | "istanbul": "0.4.5", 71 | "marked": "0.5.1", 72 | "method-override": "3.0.0", 73 | "mocha": "5.2.0", 74 | "morgan": "1.9.1", 75 | "multiparty": "4.2.1", 76 | "pbkdf2-password": "1.2.1", 77 | "should": "13.2.3", 78 | "supertest": "3.3.0", 79 | "vhost": "~3.0.2" 80 | }, 81 | "engines": { 82 | "node": ">= 0.10.0" 83 | }, 84 | "files": [ 85 | "LICENSE", 86 | "History.md", 87 | "Readme.md", 88 | "index.js", 89 | "lib/" 90 | ], 91 | "scripts": { 92 | "lint": "eslint .", 93 | "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/", 94 | "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/", 95 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/", 96 | "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/CHANGELOG: -------------------------------------------------------------------------------- 1 | ------------------------- 2 | jsSHA - ChangeLog 3 | ------------------------- 4 | 1.6.3 (2020-03-26) 5 | ========================= 6 | - Reduced ECMAScript dependency to v3 (thanks TitusInfo!) 7 | 8 | 1.6.2 (2016-05-13) 9 | ========================= 10 | - Fixed problem with hashing strings over 4 billion bits (thanks Eicar!) 11 | 12 | 1.6.1 (2015-06-25) 13 | ========================= 14 | - Fixed issue with SHA-512 family of hashes failing is raw input was a 15 | particular size 16 | 17 | 1.6.0 (2015-03-08) 18 | ========================= 19 | This marks the last v1.X new feature release. The API is changing 20 | significantly with upcoming v2.0 to support streaming and it will be too 21 | difficult to support the older API style with new features. 22 | 23 | - Added a BYTES input and output format that is a raw byte string 24 | - Fixed broken AMD support (thanks drewcovi!) 25 | - Fixed broken UTF-8 parsing on non-BMP Unicode characters 26 | - Changed array references to remove warnings on Icedove 27 | - Replaced "UTF16" encoding with "UTF16BE" (big endian) and "UTF16LE" (little 28 | endian) to remove confusion 29 | 30 | 1.5.1 (2013-12-15) 31 | ========================= 32 | - Changed Google Closure Compiler options to produce "strict" compatible code 33 | 34 | 1.5 (2013-12-15) 35 | ========================= 36 | - Added optional numRounds argument to getHash 37 | - Note: this necessitated removing the hash result caching functionality 38 | - Reduced file size by optimizing internal constants 39 | - Removed charSize input and replaced with encoding to handle Unicode. NOTE: 40 | Only Code points up to 0xFFFF are supported. 41 | - charSize = 16 is effectively replaced by encoding = "UTF16" 42 | - charSize = 8 was wrong in terms of handling UTF-8 and has been replaced by 43 | encoding = "UTF8" 44 | - Changed method of referencing "window" to be compatible with WebWorkers, 45 | Node.js, and AMD (thanks piranna!) 46 | 47 | 1.42 (2012-12-28) 48 | ========================= 49 | - Readded v1.4 Safari patch to support older versions 50 | 51 | 1.41 (2012-12-23) 52 | ========================= 53 | - Fixed incorrect hash issue with Chrome x64 v25 (Dev channel), also provides 54 | stable patch to v1.4 Safari issue. 55 | 56 | 1.4 (2012-12-08) 57 | ========================= 58 | - Added new input type, TEXT, that is functionally identical to ASCII* 59 | - Added new input type, B64, for base-64 encoded strings 60 | - Added new input and output formatting parameters 61 | - getHash and getHMAC take an optional parameter, outputFormatOpts, 62 | that is a hash list containing the keys "outputUpper" (boolean, only 63 | applicable to HEX output) and "b64Pad" (string, only applicable to Base-64 64 | output) that have default values of false and "=", respectively 65 | - jsSHA constructor takes an optional parameter, charSize (8 or 16) that 66 | specifies the character width of the input (TEXT and ASCII input only) 67 | - Modified comments to be Google Closure Compiler compliant 68 | - Added a SUPPORTED_ALGS flag that, when used with the Google Closure Compiler, 69 | will remove unused functions/function portions 70 | - Removed all src/*_nice.js files as the SUPPORTED_ALGS flag renders them 71 | obsolete 72 | - All production-ready files are now produced using the Google Closure Compiler 73 | with ADVANCED_OPTIMIZATIONS resulting in further reduced filesizes 74 | - The SHA-1 only implementation now requires that that "SHA-1" be specified as 75 | the variant when using getHash and getHMAC 76 | - Removed test/HMAC.py as new NIST tests made the need for it obsolete 77 | - Significantly changed the test/test.html to make it easier to understand and 78 | to allow for easier adding of test cases 79 | - Replaced previous error returning code with thrown exceptions 80 | - Fix for 64-bit Safari issue (thanks Ron Garret and Chris Warren-Smith!) 81 | - NOTE: While this fix works, it is merely a workaround for a WebKit JavaScript 82 | optimizer bug, see https://bugs.webkit.org/show_bug.cgi?id=88673 for more detail 83 | 84 | * This library misused the term ASCII so input type of TEXT was added with the 85 | intention of deprecating ASCII 86 | 87 | 1.31 (2012-07-21) 88 | ========================= 89 | - Updated project URL to point to new GitHub repository 90 | - Added a compressed version of sha.js 91 | 92 | 1.3 (2010-09-01) 93 | ========================= 94 | - Changed method of declaring objects/classes 95 | - Moved non-instance specific variables and methods to class scope 96 | - Removed logically correct but unneeded conditionals 97 | 98 | 1.2 (2009-07-22) 99 | ========================= 100 | - Added the HMAC algorithm for all supported hashes (using both ASCII and hex 101 | keys) 102 | - As a result of adding HMAC, added support for hash input text to be hex 103 | (ASCII representation of hex) 104 | - Added multiple variants of safeAdd functions, resulting in a significant 105 | performance gain 106 | - Removed wrapper.js file 107 | - Used a different JavaScript compressor resulting in smaller file sizes 108 | 109 | 1.11 (2008-12-07) 110 | ========================= 111 | - Fixed a base-64 encoding issue resulting from a missing capital 'X' 112 | 113 | 1.1 (2008-09-25) 114 | ========================= 115 | - Fixed an issue with incorrect hashes being generated when jsSHA ojbects were 116 | used to generate multiple hashes 117 | 118 | 1.0 (2008-09-25) 119 | ========================= 120 | - Made all functions/variables follow an object-orientated methodology 121 | - Removed support for string hash output as the hash is rarely ASCII friendly 122 | - Changed the interface to calculate hashes (see README) 123 | - Made sha.js validate against JSLint (http://www.jslint.com/) using 124 | "Recommended" settings 125 | 126 | 0.1 (2008-02-21) 127 | ========================= 128 | - Initial public release 129 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2020, Brian Turek 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | * The names of the contributors may not be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING,BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCEOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISEDOF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/README.md: -------------------------------------------------------------------------------- 1 | # jsSHA 2 | A JavaScript implementation of the complete Secure Hash Standard family 3 | (SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512) as well as HMAC by 4 | Brian Turek 5 | 6 | ## About 7 | jsSHA is a javaScript implementation of the complete Secure Hash Algorithm 8 | family as defined by FIPS PUB 180-2 9 | (http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf). 10 | 11 | It also includes the HMAC algorithm with SHA support as defined by FIPS PUB 198-1 12 | (http://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf) 13 | 14 | With the slow phasing out of MD5 as the standard hash to use in web 15 | applications, a client-side implementation of the complete Secure Hash Standard 16 | family was needed. Due to SHA-384 and SHA-512's use of 64-bit values throughout 17 | the algorithm, JavaScript can not easily natively support the calculation of 18 | these hashes. As a result, a bit of hacking had to be done to make sure the 19 | values behaved themselves. SHA-224 was added to the Secure Hash Standard family 20 | on 25 February 2004 so it was also included in this package. 21 | 22 | ## Files 23 | **src/sha_dev.js** 24 | 25 | A commented implementation of the entire SHA family of hashes. Not to be used 26 | in production. 27 | 28 | **src/sha.js** 29 | 30 | A Google Closure Compiler optimized version of the entire library 31 | 32 | **src/sha1.js** 33 | 34 | A Google Closure Compiler optimized version the library with non SHA-1 35 | functionality removed 36 | 37 | **src/sha256.js** 38 | 39 | A Google Closure Compiler optimized version the library with non SHA-224/SHA-256 40 | functionality removed 41 | 42 | **src/sha512.js** 43 | 44 | A Google Closure Compiler optimized version the library with non SHA-384/SHA-512 45 | functionality removed 46 | 47 | **test/test.html** 48 | 49 | A test page that calculates various hashes and has their correct values 50 | 51 | **test/genHashRounds.py** 52 | 53 | A Python2 script that generates multi-round hash values 54 | 55 | **build/make-release** 56 | 57 | A Bash script that runs the various Google Closure Compiler commands to build 58 | a release 59 | 60 | **build/externs.js** 61 | 62 | File needed solely to make the Google Closure Compilter work 63 | 64 | ## Usage 65 | 66 | ### Browser 67 | Include the desired JavaScript file (sha.js, sha1.js, sha256.js, or sha512.js) 68 | in your header (sha.js used below): 69 | 70 | 71 | 72 | Instantiate a new jsSHA object with your string to be hashed and its format 73 | (HEX or TEXT) as the parameters. Then, call getHash with the desired hash 74 | variant (SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512) and output type 75 | (HEX or B64). 76 | 77 | In the example below, "This is a Test" and "SHA-512" were used 78 | as the string to be hashed and variant respectively. Also, the HMAC using TEXT 79 | key "SecretKey" and hashing algorithm SHA-512 was calculated. 80 | 81 | var shaObj = new jsSHA("This is a Test", "TEXT"); 82 | var hash = shaObj.getHash("SHA-512", "HEX"); 83 | var hmac = shaObj.getHMAC("SecretKey", "TEXT", "SHA-512", "HEX"); 84 | 85 | The constructor takes an optional parameter, encoding, that specifies the 86 | encoding used to encode TEXT-type inputs. Valid options are "UTF8", "UTF16BE", 87 | and "UTF16LE", it defaults to "UTF8" 88 | 89 | getHash takes two optional parameters, a numRounds integer and an outputFormatOpts 90 | hashlist. numRounds controls the number of hashing iterations/rounds performed 91 | and defaults to a value of "1" if not specified. outputFormatOpts dictates 92 | some formatting options for the output. By default, 93 | `outputFormatOpts = {"outputUpper" : false, "b64Pad" : "="}`. These 94 | options are intelligently interpreted based upon the chosen output format. 95 | 96 | getHMAC also takes an optional outputFormatOpts hashlist which operates the exact 97 | same way as above. 98 | 99 | ### Node.js 100 | jsSHA is available through NPM and be installed by simply doing 101 | 102 | npm install jssha 103 | To use the module, first require it using: 104 | 105 | jsSHA = require("jssha"); 106 | 107 | The rest of the instructions are identical to the [Browser](#browser) section above. 108 | 109 | ## Compiling 110 | This library makes use of the Google Closure Compiler 111 | (https://developers.google.com/closure/compiler) to both boost performance 112 | and reduce filesizes. To compile sha_dev.js into a customized output file, use 113 | a command like the following: 114 | 115 | java -jar compiler.jar --define="SUPPORTED_ALGS=" \ 116 | --externs /path/to/build/externs.js --warning_level VERBOSE \ 117 | --compilation_level ADVANCED_OPTIMIZATIONS \ 118 | --js /path/to/sha_dev.js --js_output_file /path/to/sha.js 119 | 120 | where FLAG is a bitwise OR of the following values: 121 | 122 | * 4 for SHA-384/SHA-512 123 | * 2 for SHA-224/256 124 | * 1 for SHA-1 125 | 126 | ##Contact Info 127 | The project's website is located at [http://caligatio.github.com/jsSHA/](http://caligatio.github.com/jsSHA/) 128 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "jsSHA", 3 | "version" : "1.6.3", 4 | "description" : "jsSHA is a JavaScript implementation of the entire family of SHA hashes as defined in FIPS 180-2 (SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512) as well as HMAC", 5 | "main" : "src/sha.js", 6 | "repository" : { 7 | "type" : "git", 8 | "url" : "https://github.com/Caligatio/jsSHA.git" 9 | }, 10 | "keywords" : [ 11 | "SHA-1", 12 | "SHA-256", 13 | "SHA-224", 14 | "SHA-384", 15 | "SHA-512", 16 | "SHA1", 17 | "SHA256", 18 | "SHA224", 19 | "SHA384", 20 | "SHA512", 21 | "SHA2", 22 | "HMAC", 23 | "hash" 24 | ], 25 | "license" : "BSD", 26 | "authors" : [ 27 | "Brian Turek " 28 | ], 29 | "homepage" : "http://caligatio.github.com/jsSHA/", 30 | "ignore": [ 31 | "build", 32 | "test", 33 | "src/sha_dev.js" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jssha", 3 | "version": "1.6.3", 4 | "description": "jsSHA is a JavaScript implementation of the entire family of SHA hashes as defined in FIPS 180-2 (SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512) as well as HMAC", 5 | "main": "src/sha.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/Caligatio/jsSHA.git" 9 | }, 10 | "keywords": [ 11 | "SHA-1", 12 | "SHA-256", 13 | "SHA-224", 14 | "SHA-384", 15 | "SHA-512", 16 | "SHA1", 17 | "SHA256", 18 | "SHA224", 19 | "SHA384", 20 | "SHA512", 21 | "SHA2", 22 | "HMAC", 23 | "hash" 24 | ], 25 | "license": "BSD", 26 | "author": "Brian Turek ", 27 | "bugs": { 28 | "url": "https://github.com/Caligatio/jsSHA/issues" 29 | }, 30 | "engines": { 31 | "node": "*" 32 | }, 33 | "homepage": "https://github.com/Caligatio/jsSHA", 34 | "dependencies": {}, 35 | "devDependencies": {}, 36 | "scripts": { 37 | "test": "echo \"Error: no test specified\" && exit 1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nodejs/node_modules/jssha/src/sha.js: -------------------------------------------------------------------------------- 1 | /* 2 | A JavaScript implementation of the SHA family of hashes, as 3 | defined in FIPS PUB 180-2 as well as the corresponding HMAC implementation 4 | as defined in FIPS PUB 198a 5 | 6 | Copyright Brian Turek 2008-2020, 1998-2009 Paul Johnston & Contributors 7 | Distributed under the BSD License 8 | See http://caligatio.github.com/jsSHA/ for more information 9 | 10 | */ 11 | 'use strict';(function(V){function A(a,b,c){var e=0,f=[0],k="",h=null,k=c||"UTF8";if("UTF8"!==k&&"UTF16BE"!==k&&"UTF16LE"!==k)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";h=E(a);e=h.binLen;f=h.value}else if("TEXT"===b||"ASCII"===b)h=M(a,k),e=h.binLen,f=h.value;else if("B64"===b)h=N(a),e=h.binLen,f=h.value;else if("BYTES"===b)h=O(a),e=h.binLen,f=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; 12 | this.getHash=function(a,b,c,k){var h=null,d=f.slice(),n=e,m;3===arguments.length?"number"!==typeof c&&(k=c,c=1):2===arguments.length&&(c=1);if(c!==parseInt(c,10)||1>c)throw"numRounds must a integer >= 1";switch(b){case "HEX":h=P;break;case "B64":h=Q;break;case "BYTES":h=R;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-1"===a)for(m=0;mm/8){for(;d.length<=b;)d.push(0);d[b]&=4294967040}for(n=0;n<=b;n+=1)r[n]=d[n]^ 15 | 909522486,v[n]=d[n]^1549556828;c="SHA-1"===c?B(v.concat(B(r.concat(f),a+e)),a+u):x(v.concat(x(r.concat(f),a+e,c)),a+u,c);return h(c,S(q))}}function q(a,b){this.a=a;this.b=b}function M(a,b){var c=[],e,f=[],k=0,h,p,q;if("UTF8"===b)for(h=0;he?f.push(e):2048>e?(f.push(192|e>>>6),f.push(128|e&63)):55296>e||57344<=e?f.push(224|e>>>12,128|e>>>6&63,128|e&63):(h+=1,e=65536+((e&1023)<<10|a.charCodeAt(h)&1023),f.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|e&63)), 16 | p=0;p>>2;c.length<=q;)c.push(0);c[q]|=f[p]<<24-k%4*8;k+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(h=0;h>8);for(q=k>>>2;c.length<=q;)c.push(0);c[q]|=e<<16-k%4*8;k+=2}return{value:c,binLen:8*k}}function E(a){var b=[],c=a.length,e,f,k;if(0!==c%2)throw"String of HEX type must be in byte increments";for(e=0;e>>3;b.length<=k;)b.push(0);b[e>>>3]|=f<<24-e%8*4}return{value:b,binLen:4*c}}function O(a){var b=[],c,e,f;for(e=0;e>>2,b.length<=f&&b.push(0),b[f]|=c<<24-e%4*8;return{value:b,binLen:8*a.length}}function N(a){var b=[],c=0,e,f,k,h,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string";f=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==f&&f Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. 11 | 12 | ## API 13 | 14 | 15 | 16 | ```js 17 | var morgan = require('morgan') 18 | ``` 19 | 20 | ### morgan(format, options) 21 | 22 | Create a new morgan logger middleware function using the given `format` and `options`. 23 | The `format` argument may be a string of a predefined name (see below for the names), 24 | a string of a format string, or a function that will produce a log entry. 25 | 26 | The `format` function will be called with three arguments `tokens`, `req`, and `res`, 27 | where `tokens` is an object with all defined tokens, `req` is the HTTP request and `res` 28 | is the HTTP response. The function is expected to return a string that will be the log 29 | line, or `undefined` / `null` to skip logging. 30 | 31 | #### Using a predefined format string 32 | 33 | 34 | 35 | ```js 36 | morgan('tiny') 37 | ``` 38 | 39 | #### Using format string of predefined tokens 40 | 41 | 42 | 43 | ```js 44 | morgan(':method :url :status :res[content-length] - :response-time ms') 45 | ``` 46 | 47 | #### Using a custom format function 48 | 49 | 50 | 51 | ``` js 52 | morgan(function (tokens, req, res) { 53 | return [ 54 | tokens.method(req, res), 55 | tokens.url(req, res), 56 | tokens.status(req, res), 57 | tokens.res(req, res, 'content-length'), '-', 58 | tokens['response-time'](req, res), 'ms' 59 | ].join(' ') 60 | }) 61 | ``` 62 | 63 | #### Options 64 | 65 | Morgan accepts these properties in the options object. 66 | 67 | ##### immediate 68 | 69 | Write log line on request instead of response. This means that a requests will 70 | be logged even if the server crashes, _but data from the response (like the 71 | response code, content length, etc.) cannot be logged_. 72 | 73 | ##### skip 74 | 75 | Function to determine if logging is skipped, defaults to `false`. This function 76 | will be called as `skip(req, res)`. 77 | 78 | 79 | 80 | ```js 81 | // EXAMPLE: only log error responses 82 | morgan('combined', { 83 | skip: function (req, res) { return res.statusCode < 400 } 84 | }) 85 | ``` 86 | 87 | ##### stream 88 | 89 | Output stream for writing log lines, defaults to `process.stdout`. 90 | 91 | #### Predefined Formats 92 | 93 | There are various pre-defined formats provided: 94 | 95 | ##### combined 96 | 97 | Standard Apache combined log output. 98 | 99 | ``` 100 | :remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" 101 | ``` 102 | 103 | ##### common 104 | 105 | Standard Apache common log output. 106 | 107 | ``` 108 | :remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] 109 | ``` 110 | 111 | ##### dev 112 | 113 | Concise output colored by response status for development use. The `:status` 114 | token will be colored red for server error codes, yellow for client error 115 | codes, cyan for redirection codes, and uncolored for all other codes. 116 | 117 | ``` 118 | :method :url :status :response-time ms - :res[content-length] 119 | ``` 120 | 121 | ##### short 122 | 123 | Shorter than default, also including response time. 124 | 125 | ``` 126 | :remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms 127 | ``` 128 | 129 | ##### tiny 130 | 131 | The minimal output. 132 | 133 | ``` 134 | :method :url :status :res[content-length] - :response-time ms 135 | ``` 136 | 137 | #### Tokens 138 | 139 | ##### Creating new tokens 140 | 141 | To define a token, simply invoke `morgan.token()` with the name and a callback function. 142 | This callback function is expected to return a string value. The value returned is then 143 | available as ":type" in this case: 144 | 145 | 146 | 147 | ```js 148 | morgan.token('type', function (req, res) { return req.headers['content-type'] }) 149 | ``` 150 | 151 | Calling `morgan.token()` using the same name as an existing token will overwrite that 152 | token definition. 153 | 154 | The token function is expected to be called with the arguments `req` and `res`, representing 155 | the HTTP request and HTTP response. Additionally, the token can accept further arguments of 156 | it's choosing to customize behavior. 157 | 158 | ##### :date[format] 159 | 160 | The current date and time in UTC. The available formats are: 161 | 162 | - `clf` for the common log format (`"10/Oct/2000:13:55:36 +0000"`) 163 | - `iso` for the common ISO 8601 date time format (`2000-10-10T13:55:36.000Z`) 164 | - `web` for the common RFC 1123 date time format (`Tue, 10 Oct 2000 13:55:36 GMT`) 165 | 166 | If no format is given, then the default is `web`. 167 | 168 | ##### :http-version 169 | 170 | The HTTP version of the request. 171 | 172 | ##### :method 173 | 174 | The HTTP method of the request. 175 | 176 | ##### :referrer 177 | 178 | The Referrer header of the request. This will use the standard mis-spelled Referer header if exists, otherwise Referrer. 179 | 180 | ##### :remote-addr 181 | 182 | The remote address of the request. This will use `req.ip`, otherwise the standard `req.connection.remoteAddress` value (socket address). 183 | 184 | ##### :remote-user 185 | 186 | The user authenticated as part of Basic auth for the request. 187 | 188 | ##### :req[header] 189 | 190 | The given `header` of the request. If the header is not present, the 191 | value will be displayed as `"-"` in the log. 192 | 193 | ##### :res[header] 194 | 195 | The given `header` of the response. If the header is not present, the 196 | value will be displayed as `"-"` in the log. 197 | 198 | ##### :response-time[digits] 199 | 200 | The time between the request coming into `morgan` and when the response 201 | headers are written, in milliseconds. 202 | 203 | The `digits` argument is a number that specifies the number of digits to 204 | include on the number, defaulting to `3`, which provides microsecond precision. 205 | 206 | ##### :status 207 | 208 | The status code of the response. 209 | 210 | If the request/response cycle completes before a response was sent to the 211 | client (for example, the TCP socket closed prematurely by a client aborting 212 | the request), then the status will be empty (displayed as `"-"` in the log). 213 | 214 | ##### :url 215 | 216 | The URL of the request. This will use `req.originalUrl` if exists, otherwise `req.url`. 217 | 218 | ##### :user-agent 219 | 220 | The contents of the User-Agent header of the request. 221 | 222 | ### morgan.compile(format) 223 | 224 | Compile a format string into a `format` function for use by `morgan`. A format string 225 | is a string that represents a single log line and can utilize token syntax. 226 | Tokens are references by `:token-name`. If tokens accept arguments, they can 227 | be passed using `[]`, for example: `:token-name[pretty]` would pass the string 228 | `'pretty'` as an argument to the token `token-name`. 229 | 230 | The function returned from `morgan.compile` takes three arguments `tokens`, `req`, and 231 | `res`, where `tokens` is object with all defined tokens, `req` is the HTTP request and 232 | `res` is the HTTP response. The function will return a string that will be the log line, 233 | or `undefined` / `null` to skip logging. 234 | 235 | Normally formats are defined using `morgan.format(name, format)`, but for certain 236 | advanced uses, this compile function is directly available. 237 | 238 | ## Examples 239 | 240 | ### express/connect 241 | 242 | Simple app that will log all request in the Apache combined format to STDOUT 243 | 244 | ```js 245 | var express = require('express') 246 | var morgan = require('morgan') 247 | 248 | var app = express() 249 | 250 | app.use(morgan('combined')) 251 | 252 | app.get('/', function (req, res) { 253 | res.send('hello, world!') 254 | }) 255 | ``` 256 | 257 | ### vanilla http server 258 | 259 | Simple app that will log all request in the Apache combined format to STDOUT 260 | 261 | ```js 262 | var finalhandler = require('finalhandler') 263 | var http = require('http') 264 | var morgan = require('morgan') 265 | 266 | // create "middleware" 267 | var logger = morgan('combined') 268 | 269 | http.createServer(function (req, res) { 270 | var done = finalhandler(req, res) 271 | logger(req, res, function (err) { 272 | if (err) return done(err) 273 | 274 | // respond to request 275 | res.setHeader('content-type', 'text/plain') 276 | res.end('hello, world!') 277 | }) 278 | }) 279 | ``` 280 | 281 | ### write logs to a file 282 | 283 | #### single file 284 | 285 | Simple app that will log all requests in the Apache combined format to the file 286 | `access.log`. 287 | 288 | ```js 289 | var express = require('express') 290 | var fs = require('fs') 291 | var morgan = require('morgan') 292 | var path = require('path') 293 | 294 | var app = express() 295 | 296 | // create a write stream (in append mode) 297 | var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }) 298 | 299 | // setup the logger 300 | app.use(morgan('combined', { stream: accessLogStream })) 301 | 302 | app.get('/', function (req, res) { 303 | res.send('hello, world!') 304 | }) 305 | ``` 306 | 307 | #### log file rotation 308 | 309 | Simple app that will log all requests in the Apache combined format to one log 310 | file per day in the `log/` directory using the 311 | [rotating-file-stream module](https://www.npmjs.com/package/rotating-file-stream). 312 | 313 | ```js 314 | var express = require('express') 315 | var fs = require('fs') 316 | var morgan = require('morgan') 317 | var path = require('path') 318 | var rfs = require('rotating-file-stream') 319 | 320 | var app = express() 321 | var logDirectory = path.join(__dirname, 'log') 322 | 323 | // ensure log directory exists 324 | fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory) 325 | 326 | // create a rotating write stream 327 | var accessLogStream = rfs('access.log', { 328 | interval: '1d', // rotate daily 329 | path: logDirectory 330 | }) 331 | 332 | // setup the logger 333 | app.use(morgan('combined', { stream: accessLogStream })) 334 | 335 | app.get('/', function (req, res) { 336 | res.send('hello, world!') 337 | }) 338 | ``` 339 | 340 | ### split / dual logging 341 | 342 | The `morgan` middleware can be used as many times as needed, enabling 343 | combinations like: 344 | 345 | * Log entry on request and one on response 346 | * Log all requests to file, but errors to console 347 | * ... and more! 348 | 349 | Sample app that will log all requests to a file using Apache format, but 350 | error responses are logged to the console: 351 | 352 | ```js 353 | var express = require('express') 354 | var fs = require('fs') 355 | var morgan = require('morgan') 356 | var path = require('path') 357 | 358 | var app = express() 359 | 360 | // log only 4xx and 5xx responses to console 361 | app.use(morgan('dev', { 362 | skip: function (req, res) { return res.statusCode < 400 } 363 | })) 364 | 365 | // log all requests to access.log 366 | app.use(morgan('common', { 367 | stream: fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' }) 368 | })) 369 | 370 | app.get('/', function (req, res) { 371 | res.send('hello, world!') 372 | }) 373 | ``` 374 | 375 | ### use custom token formats 376 | 377 | Sample app that will use custom token formats. This adds an ID to all requests and displays it using the `:id` token. 378 | 379 | ```js 380 | var express = require('express') 381 | var morgan = require('morgan') 382 | var uuid = require('node-uuid') 383 | 384 | morgan.token('id', function getId (req) { 385 | return req.id 386 | }) 387 | 388 | var app = express() 389 | 390 | app.use(assignId) 391 | app.use(morgan(':id :method :url :response-time')) 392 | 393 | app.get('/', function (req, res) { 394 | res.send('hello, world!') 395 | }) 396 | 397 | function assignId (req, res, next) { 398 | req.id = uuid.v4() 399 | next() 400 | } 401 | ``` 402 | 403 | ## License 404 | 405 | [MIT](LICENSE) 406 | 407 | [npm-image]: https://img.shields.io/npm/v/morgan.svg 408 | [npm-url]: https://npmjs.org/package/morgan 409 | [travis-image]: https://img.shields.io/travis/expressjs/morgan/master.svg 410 | [travis-url]: https://travis-ci.org/expressjs/morgan 411 | [coveralls-image]: https://img.shields.io/coveralls/expressjs/morgan/master.svg 412 | [coveralls-url]: https://coveralls.io/r/expressjs/morgan?branch=master 413 | [downloads-image]: https://img.shields.io/npm/dm/morgan.svg 414 | [downloads-url]: https://npmjs.org/package/morgan 415 | -------------------------------------------------------------------------------- /nodejs/node_modules/morgan/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * morgan 3 | * Copyright(c) 2010 Sencha Inc. 4 | * Copyright(c) 2011 TJ Holowaychuk 5 | * Copyright(c) 2014 Jonathan Ong 6 | * Copyright(c) 2014-2017 Douglas Christopher Wilson 7 | * MIT Licensed 8 | */ 9 | 10 | 'use strict' 11 | 12 | /** 13 | * Module exports. 14 | * @public 15 | */ 16 | 17 | module.exports = morgan 18 | module.exports.compile = compile 19 | module.exports.format = format 20 | module.exports.token = token 21 | 22 | /** 23 | * Module dependencies. 24 | * @private 25 | */ 26 | 27 | var auth = require('basic-auth') 28 | var debug = require('debug')('morgan') 29 | var deprecate = require('depd')('morgan') 30 | var onFinished = require('on-finished') 31 | var onHeaders = require('on-headers') 32 | 33 | /** 34 | * Array of CLF month names. 35 | * @private 36 | */ 37 | 38 | var CLF_MONTH = [ 39 | 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 40 | 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' 41 | ] 42 | 43 | /** 44 | * Default log buffer duration. 45 | * @private 46 | */ 47 | 48 | var DEFAULT_BUFFER_DURATION = 1000 49 | 50 | /** 51 | * Create a logger middleware. 52 | * 53 | * @public 54 | * @param {String|Function} format 55 | * @param {Object} [options] 56 | * @return {Function} middleware 57 | */ 58 | 59 | function morgan (format, options) { 60 | var fmt = format 61 | var opts = options || {} 62 | 63 | if (format && typeof format === 'object') { 64 | opts = format 65 | fmt = opts.format || 'default' 66 | 67 | // smart deprecation message 68 | deprecate('morgan(options): use morgan(' + (typeof fmt === 'string' ? JSON.stringify(fmt) : 'format') + ', options) instead') 69 | } 70 | 71 | if (fmt === undefined) { 72 | deprecate('undefined format: specify a format') 73 | } 74 | 75 | // output on request instead of response 76 | var immediate = opts.immediate 77 | 78 | // check if log entry should be skipped 79 | var skip = opts.skip || false 80 | 81 | // format function 82 | var formatLine = typeof fmt !== 'function' 83 | ? getFormatFunction(fmt) 84 | : fmt 85 | 86 | // stream 87 | var buffer = opts.buffer 88 | var stream = opts.stream || process.stdout 89 | 90 | // buffering support 91 | if (buffer) { 92 | deprecate('buffer option') 93 | 94 | // flush interval 95 | var interval = typeof buffer !== 'number' 96 | ? DEFAULT_BUFFER_DURATION 97 | : buffer 98 | 99 | // swap the stream 100 | stream = createBufferStream(stream, interval) 101 | } 102 | 103 | return function logger (req, res, next) { 104 | // request data 105 | req._startAt = undefined 106 | req._startTime = undefined 107 | req._remoteAddress = getip(req) 108 | 109 | // response data 110 | res._startAt = undefined 111 | res._startTime = undefined 112 | 113 | // record request start 114 | recordStartTime.call(req) 115 | 116 | function logRequest () { 117 | if (skip !== false && skip(req, res)) { 118 | debug('skip request') 119 | return 120 | } 121 | 122 | var line = formatLine(morgan, req, res) 123 | 124 | if (line == null) { 125 | debug('skip line') 126 | return 127 | } 128 | 129 | debug('log request') 130 | stream.write(line + '\n') 131 | }; 132 | 133 | if (immediate) { 134 | // immediate log 135 | logRequest() 136 | } else { 137 | // record response start 138 | onHeaders(res, recordStartTime) 139 | 140 | // log when response finished 141 | onFinished(res, logRequest) 142 | } 143 | 144 | next() 145 | } 146 | } 147 | 148 | /** 149 | * Apache combined log format. 150 | */ 151 | 152 | morgan.format('combined', ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"') 153 | 154 | /** 155 | * Apache common log format. 156 | */ 157 | 158 | morgan.format('common', ':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]') 159 | 160 | /** 161 | * Default format. 162 | */ 163 | 164 | morgan.format('default', ':remote-addr - :remote-user [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"') 165 | deprecate.property(morgan, 'default', 'default format: use combined format') 166 | 167 | /** 168 | * Short format. 169 | */ 170 | 171 | morgan.format('short', ':remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms') 172 | 173 | /** 174 | * Tiny format. 175 | */ 176 | 177 | morgan.format('tiny', ':method :url :status :res[content-length] - :response-time ms') 178 | 179 | /** 180 | * dev (colored) 181 | */ 182 | 183 | morgan.format('dev', function developmentFormatLine (tokens, req, res) { 184 | // get the status code if response written 185 | var status = headersSent(res) 186 | ? res.statusCode 187 | : undefined 188 | 189 | // get status color 190 | var color = status >= 500 ? 31 // red 191 | : status >= 400 ? 33 // yellow 192 | : status >= 300 ? 36 // cyan 193 | : status >= 200 ? 32 // green 194 | : 0 // no color 195 | 196 | // get colored function 197 | var fn = developmentFormatLine[color] 198 | 199 | if (!fn) { 200 | // compile 201 | fn = developmentFormatLine[color] = compile('\x1b[0m:method :url \x1b[' + 202 | color + 'm:status \x1b[0m:response-time ms - :res[content-length]\x1b[0m') 203 | } 204 | 205 | return fn(tokens, req, res) 206 | }) 207 | 208 | /** 209 | * request url 210 | */ 211 | 212 | morgan.token('url', function getUrlToken (req) { 213 | return req.originalUrl || req.url 214 | }) 215 | 216 | /** 217 | * request method 218 | */ 219 | 220 | morgan.token('method', function getMethodToken (req) { 221 | return req.method 222 | }) 223 | 224 | /** 225 | * response time in milliseconds 226 | */ 227 | 228 | morgan.token('response-time', function getResponseTimeToken (req, res, digits) { 229 | if (!req._startAt || !res._startAt) { 230 | // missing request and/or response start time 231 | return 232 | } 233 | 234 | // calculate diff 235 | var ms = (res._startAt[0] - req._startAt[0]) * 1e3 + 236 | (res._startAt[1] - req._startAt[1]) * 1e-6 237 | 238 | // return truncated value 239 | return ms.toFixed(digits === undefined ? 3 : digits) 240 | }) 241 | 242 | /** 243 | * current date 244 | */ 245 | 246 | morgan.token('date', function getDateToken (req, res, format) { 247 | var date = new Date() 248 | 249 | switch (format || 'web') { 250 | case 'clf': 251 | return clfdate(date) 252 | case 'iso': 253 | return date.toISOString() 254 | case 'web': 255 | return date.toUTCString() 256 | } 257 | }) 258 | 259 | /** 260 | * response status code 261 | */ 262 | 263 | morgan.token('status', function getStatusToken (req, res) { 264 | return headersSent(res) 265 | ? String(res.statusCode) 266 | : undefined 267 | }) 268 | 269 | /** 270 | * normalized referrer 271 | */ 272 | 273 | morgan.token('referrer', function getReferrerToken (req) { 274 | return req.headers['referer'] || req.headers['referrer'] 275 | }) 276 | 277 | /** 278 | * remote address 279 | */ 280 | 281 | morgan.token('remote-addr', getip) 282 | 283 | /** 284 | * remote user 285 | */ 286 | 287 | morgan.token('remote-user', function getRemoteUserToken (req) { 288 | // parse basic credentials 289 | var credentials = auth(req) 290 | 291 | // return username 292 | return credentials 293 | ? credentials.name 294 | : undefined 295 | }) 296 | 297 | /** 298 | * HTTP version 299 | */ 300 | 301 | morgan.token('http-version', function getHttpVersionToken (req) { 302 | return req.httpVersionMajor + '.' + req.httpVersionMinor 303 | }) 304 | 305 | /** 306 | * UA string 307 | */ 308 | 309 | morgan.token('user-agent', function getUserAgentToken (req) { 310 | return req.headers['user-agent'] 311 | }) 312 | 313 | /** 314 | * request header 315 | */ 316 | 317 | morgan.token('req', function getRequestToken (req, res, field) { 318 | // get header 319 | var header = req.headers[field.toLowerCase()] 320 | 321 | return Array.isArray(header) 322 | ? header.join(', ') 323 | : header 324 | }) 325 | 326 | /** 327 | * response header 328 | */ 329 | 330 | morgan.token('res', function getResponseHeader (req, res, field) { 331 | if (!headersSent(res)) { 332 | return undefined 333 | } 334 | 335 | // get header 336 | var header = res.getHeader(field) 337 | 338 | return Array.isArray(header) 339 | ? header.join(', ') 340 | : header 341 | }) 342 | 343 | /** 344 | * Format a Date in the common log format. 345 | * 346 | * @private 347 | * @param {Date} dateTime 348 | * @return {string} 349 | */ 350 | 351 | function clfdate (dateTime) { 352 | var date = dateTime.getUTCDate() 353 | var hour = dateTime.getUTCHours() 354 | var mins = dateTime.getUTCMinutes() 355 | var secs = dateTime.getUTCSeconds() 356 | var year = dateTime.getUTCFullYear() 357 | 358 | var month = CLF_MONTH[dateTime.getUTCMonth()] 359 | 360 | return pad2(date) + '/' + month + '/' + year + 361 | ':' + pad2(hour) + ':' + pad2(mins) + ':' + pad2(secs) + 362 | ' +0000' 363 | } 364 | 365 | /** 366 | * Compile a format string into a function. 367 | * 368 | * @param {string} format 369 | * @return {function} 370 | * @public 371 | */ 372 | 373 | function compile (format) { 374 | if (typeof format !== 'string') { 375 | throw new TypeError('argument format must be a string') 376 | } 377 | 378 | var fmt = String(JSON.stringify(format)) 379 | var js = ' "use strict"\n return ' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function (_, name, arg) { 380 | var tokenArguments = 'req, res' 381 | var tokenFunction = 'tokens[' + String(JSON.stringify(name)) + ']' 382 | 383 | if (arg !== undefined) { 384 | tokenArguments += ', ' + String(JSON.stringify(arg)) 385 | } 386 | 387 | return '" +\n (' + tokenFunction + '(' + tokenArguments + ') || "-") + "' 388 | }) 389 | 390 | // eslint-disable-next-line no-new-func 391 | return new Function('tokens, req, res', js) 392 | } 393 | 394 | /** 395 | * Create a basic buffering stream. 396 | * 397 | * @param {object} stream 398 | * @param {number} interval 399 | * @public 400 | */ 401 | 402 | function createBufferStream (stream, interval) { 403 | var buf = [] 404 | var timer = null 405 | 406 | // flush function 407 | function flush () { 408 | timer = null 409 | stream.write(buf.join('')) 410 | buf.length = 0 411 | } 412 | 413 | // write function 414 | function write (str) { 415 | if (timer === null) { 416 | timer = setTimeout(flush, interval) 417 | } 418 | 419 | buf.push(str) 420 | } 421 | 422 | // return a minimal "stream" 423 | return { write: write } 424 | } 425 | 426 | /** 427 | * Define a format with the given name. 428 | * 429 | * @param {string} name 430 | * @param {string|function} fmt 431 | * @public 432 | */ 433 | 434 | function format (name, fmt) { 435 | morgan[name] = fmt 436 | return this 437 | } 438 | 439 | /** 440 | * Lookup and compile a named format function. 441 | * 442 | * @param {string} name 443 | * @return {function} 444 | * @public 445 | */ 446 | 447 | function getFormatFunction (name) { 448 | // lookup format 449 | var fmt = morgan[name] || name || morgan.default 450 | 451 | // return compiled format 452 | return typeof fmt !== 'function' 453 | ? compile(fmt) 454 | : fmt 455 | } 456 | 457 | /** 458 | * Get request IP address. 459 | * 460 | * @private 461 | * @param {IncomingMessage} req 462 | * @return {string} 463 | */ 464 | 465 | function getip (req) { 466 | return req.ip || 467 | req._remoteAddress || 468 | (req.connection && req.connection.remoteAddress) || 469 | undefined 470 | } 471 | 472 | /** 473 | * Determine if the response headers have been sent. 474 | * 475 | * @param {object} res 476 | * @returns {boolean} 477 | * @private 478 | */ 479 | 480 | function headersSent (res) { 481 | return typeof res.headersSent !== 'boolean' 482 | ? Boolean(res._header) 483 | : res.headersSent 484 | } 485 | 486 | /** 487 | * Pad number to two digits. 488 | * 489 | * @private 490 | * @param {number} num 491 | * @return {string} 492 | */ 493 | 494 | function pad2 (num) { 495 | var str = String(num) 496 | 497 | return (str.length === 1 ? '0' : '') + str 498 | } 499 | 500 | /** 501 | * Record the start time. 502 | * @private 503 | */ 504 | 505 | function recordStartTime () { 506 | this._startAt = process.hrtime() 507 | this._startTime = new Date() 508 | } 509 | 510 | /** 511 | * Define a token function with the given name, 512 | * and callback fn(req, res). 513 | * 514 | * @param {string} name 515 | * @param {function} fn 516 | * @public 517 | */ 518 | 519 | function token (name, fn) { 520 | morgan[name] = fn 521 | return this 522 | } 523 | -------------------------------------------------------------------------------- /nodejs/node_modules/morgan/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "morgan", 3 | "description": "HTTP request logger middleware for node.js", 4 | "version": "1.9.1", 5 | "contributors": [ 6 | "Douglas Christopher Wilson ", 7 | "Jonathan Ong (http://jongleberry.com)" 8 | ], 9 | "license": "MIT", 10 | "keywords": [ 11 | "express", 12 | "http", 13 | "logger", 14 | "middleware" 15 | ], 16 | "repository": "expressjs/morgan", 17 | "dependencies": { 18 | "basic-auth": "~2.0.0", 19 | "debug": "2.6.9", 20 | "depd": "~1.1.2", 21 | "on-finished": "~2.3.0", 22 | "on-headers": "~1.0.1" 23 | }, 24 | "devDependencies": { 25 | "eslint": "5.5.0", 26 | "eslint-config-standard": "12.0.0", 27 | "eslint-plugin-import": "2.14.0", 28 | "eslint-plugin-markdown": "1.0.0-beta.6", 29 | "eslint-plugin-node": "7.0.1", 30 | "eslint-plugin-promise": "4.0.1", 31 | "eslint-plugin-standard": "4.0.0", 32 | "istanbul": "0.4.5", 33 | "mocha": "2.5.3", 34 | "split": "1.0.1", 35 | "supertest": "1.1.0" 36 | }, 37 | "files": [ 38 | "LICENSE", 39 | "HISTORY.md", 40 | "README.md", 41 | "index.js" 42 | ], 43 | "engines": { 44 | "node": ">= 0.8.0" 45 | }, 46 | "scripts": { 47 | "lint": "eslint --plugin markdown --ext js,md .", 48 | "test": "mocha --check-leaks --reporter spec --bail", 49 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot", 50 | "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "jssha": "^1.5.0", 10 | "cookie-parser": "~1.4.4", 11 | "debug": "~2.6.9", 12 | "express": "~4.16.1", 13 | "http-errors": "~1.6.3", 14 | "jade": "~1.11.0", 15 | "morgan": "~1.9.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /nodejs/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /nodejs/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | /* GET home page. */ 4 | router.get('/', function(req, res, next) { 5 | res.render('index', { title: 'Express' }); 6 | }); 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /nodejs/routes/wechat.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | var http = require("http"); 5 | var https = require("https"); 6 | var jsSHA = require('jssha'); 7 | 8 | 9 | // 输出数字签名对象 10 | var responseWithJson = function (res, data) { 11 | // 允许跨域异步获取 12 | res.set({ 13 | "Access-Control-Allow-Origin": "*" 14 | ,"Access-Control-Allow-Methods": "POST,GET" 15 | ,"Access-Control-Allow-Credentials": "true" 16 | }); 17 | res.json(data); 18 | }; 19 | 20 | // 随机字符串产生函数 21 | var createNonceStr = function() { 22 | return Math.random().toString(36).substr(2, 15); 23 | }; 24 | 25 | // 时间戳产生函数 26 | var createTimeStamp = function () { 27 | return parseInt(new Date().getTime() / 1000) + ''; 28 | }; 29 | 30 | var errorRender = function (res, info, data) { 31 | if(data){ 32 | console.log(data); 33 | console.log('---------'); 34 | } 35 | res.set({ 36 | "Access-Control-Allow-Origin": "*" 37 | ,"Access-Control-Allow-Methods": "POST,GET" 38 | ,"Access-Control-Allow-Credentials": "true" 39 | }); 40 | responseWithJson(res, {errmsg: 'error', message: info, data: data}); 41 | }; 42 | 43 | // 2小时后过期,需要重新获取数据后计算签名 44 | var expireTime = 7200 - 100; 45 | 46 | /** 47 | 公司运营的各个公众平台appid及secret 48 | 对象结构如: 49 | [{ 50 | appid: 'wxa0f06601f19433af' 51 | ,secret: '097fd14bac218d0fb016d02f525d0b1e' 52 | }] 53 | */ 54 | // 路径为'xxx/rsx/0'时表示榕树下 55 | // 路径为'xxx/rsx/1'时表示榕树下其它产品的公众帐号 56 | // 以此以0,1,2代表数组中的不同公众帐号 57 | // 以rsx或其它路径文件夹代表不同公司产品 58 | var getAppsInfo = require('./../appsInfo'); // 从外部加载app的配置信息 59 | var appIds = getAppsInfo(); 60 | /** 61 | 缓存在服务器的每个URL对应的数字签名对象 62 | { 63 | 'https://tiepili.com/': { 64 | appid: 'wxa0f06601f194xxxx' 65 | ,secret: '097fd14bac218d0fb016d02f525dxxxx' 66 | ,timestamp: '1421135250' 67 | ,noncestr: 'ihj9ezfxf26jq0k' 68 | } 69 | } 70 | */ 71 | var cachedSignatures = {}; 72 | 73 | // 计算签名 74 | var calcSignature = function (ticket, noncestr, ts, url) { 75 | var str = 'jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '×tamp='+ ts +'&url=' + url; 76 | shaObj = new jsSHA(str, 'TEXT'); 77 | return shaObj.getHash('SHA-1', 'HEX'); 78 | } 79 | 80 | // 获取微信签名所需的ticket 81 | var getTicket = function (url, index, res, accessData) { 82 | https.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='+ accessData.access_token +'&type=jsapi', function(_res){ 83 | var str = '', resp; 84 | _res.on('data', function(data){ 85 | str += data; 86 | }); 87 | _res.on('end', function(){ 88 | console.log('return ticket: ' + str); 89 | try{ 90 | resp = JSON.parse(str); 91 | }catch(e){ 92 | return errorRender(res, '解析远程JSON数据错误', str); 93 | } 94 | 95 | var appid = appIds[index].appid; 96 | var ts = createTimeStamp(); 97 | var nonceStr = createNonceStr(); 98 | var ticket = resp.ticket; 99 | var signature = calcSignature(ticket, nonceStr, ts, url); 100 | 101 | cachedSignatures[url] = { 102 | nonceStr: nonceStr 103 | ,appid: appid 104 | ,timestamp: ts 105 | ,signature: signature 106 | ,url: url 107 | }; 108 | 109 | responseWithJson(res, { 110 | nonceStr: nonceStr 111 | ,timestamp: ts 112 | ,appid: appid 113 | ,signature: signature 114 | ,url: url 115 | }); 116 | }); 117 | }); 118 | }; 119 | 120 | 121 | // 通过请求中带的 index 值来判断是公司运营的哪个公众平台 122 | router.post('/:index', function(req, res, next) { 123 | var index = req.params.index; 124 | var _url = req.body.url; 125 | var signatureObj = cachedSignatures[_url]; 126 | if(!_url){ 127 | return errorRender(res, '缺少url参数'); 128 | } 129 | 130 | // 如果缓存中已存在签名,则直接返回签名 131 | if(signatureObj && signatureObj.timestamp){ 132 | var t = createTimeStamp() - signatureObj.timestamp; 133 | // 未过期,并且访问的是同一个地址 134 | // 判断地址是因为微信分享出去后会额外添加一些参数,地址就变了不符合签名规则,需重新生成签名 135 | if(t < expireTime && signatureObj.url == _url){ 136 | console.log('======== result from cache ========'); 137 | return responseWithJson(res, { 138 | nonceStr: signatureObj.nonceStr, 139 | timestamp: signatureObj.timestamp, 140 | appid: signatureObj.appid, 141 | signature: signatureObj.signature, 142 | url: signatureObj.url 143 | }); 144 | } 145 | // 此处可能需要清理缓存当中已过期的数据 146 | } 147 | 148 | // 获取微信签名所需的access_token 149 | https.get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+ appIds[index].appid +'&secret=' + appIds[index].secret, function(_res) { 150 | var str = ''; 151 | _res.on('data', function(data){ 152 | str += data; 153 | }); 154 | _res.on('end', function(){ 155 | console.log('return access_token: ' + str); 156 | try{ 157 | var resp = JSON.parse(str); 158 | }catch(e){ 159 | return errorRender(res, '解析access_token返回的JSON数据错误', str); 160 | } 161 | getTicket(_url, index, res, resp); 162 | }); 163 | }) 164 | // res.send('respond with a resource'); 165 | }); 166 | 167 | module.exports = router; 168 | -------------------------------------------------------------------------------- /nodejs/views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /nodejs/views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /nodejs/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content 8 | -------------------------------------------------------------------------------- /web/css/index.css: -------------------------------------------------------------------------------- 1 | *{ 2 | padding: 0; 3 | margin: 0; 4 | } 5 | body{ 6 | width: 375px; 7 | margin: 0 auto; 8 | } -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 测试 demo 7 | 8 | 9 | 10 |

测试 wechat share sdk demo

11 | 12 | 13 | 55 | 56 | --------------------------------------------------------------------------------