최원섭

[Update] Express Version Modified

1 +var express = require('express');
2 +var path = require('path');
3 +var favicon = require('serve-favicon');
4 +var logger = require('morgan');
5 +var cookieParser = require('cookie-parser');
6 +var bodyParser = require('body-parser');
7 +
8 +var message = require('./routes/message');
9 +var keyboard = require('./routes/keyboard');
10 +var app = express();
11 +
12 +// view engine setup
13 +app.set('views', path.join(__dirname, 'views'));
14 +app.set('view engine', 'ejs');
15 +
16 +// uncomment after placing your favicon in /public
17 +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
18 +app.use(logger('dev'));
19 +app.use(bodyParser.json());
20 +app.use(bodyParser.urlencoded({ extended: false }));
21 +app.use(cookieParser());
22 +app.use(express.static(path.join(__dirname, 'public')));
23 +
24 +app.use('/keyboard',keyboard);
25 +app.use('/message',message);
26 +
27 +// catch 404 and forward to error handler
28 +app.use(function(req, res, next) {
29 + var err = new Error('Not Found');
30 + err.status = 404;
31 + next(err);
32 +});
33 +
34 +// error handler
35 +app.use(function(err, req, res, next) {
36 + // set locals, only providing error in development
37 + res.locals.message = err.message;
38 + res.locals.error = req.app.get('env') === 'development' ? err : {};
39 +
40 + // render the error page
41 + res.status(err.status || 500);
42 + res.render('error');
43 +});
44 +
45 +module.exports = app;
46 +
1 +#!/usr/bin/env node
2 +
3 +/**
4 + * Module dependencies.
5 + */
6 +
7 +var app = require('../app');
8 +var debug = require('debug')('project: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 || '80');
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 +}
1 +2.0.0 / 2017-09-12
2 +==================
3 +
4 + * Drop support for Node.js below 0.8
5 + * Remove `auth(ctx)` signature -- pass in header or `auth(ctx.req)`
6 + * Use `safe-buffer` for improved Buffer API
7 +
8 +1.1.0 / 2016-11-18
9 +==================
10 +
11 + * Add `auth.parse` for low-level string parsing
12 +
13 +1.0.4 / 2016-05-10
14 +==================
15 +
16 + * Improve error message when `req` argument is not an object
17 + * Improve error message when `req` missing `headers` property
18 +
19 +1.0.3 / 2015-07-01
20 +==================
21 +
22 + * Fix regression accepting a Koa context
23 +
24 +1.0.2 / 2015-06-12
25 +==================
26 +
27 + * Improve error message when `req` argument missing
28 + * perf: enable strict mode
29 + * perf: hoist regular expression
30 + * perf: parse with regular expressions
31 + * perf: remove argument reassignment
32 +
33 +1.0.1 / 2015-05-04
34 +==================
35 +
36 + * Update readme
37 +
38 +1.0.0 / 2014-07-01
39 +==================
40 +
41 + * Support empty password
42 + * Support empty username
43 +
44 +0.0.1 / 2013-11-30
45 +==================
46 +
47 + * Initial release
1 +(The MIT License)
2 +
3 +Copyright (c) 2013 TJ Holowaychuk
4 +Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
5 +Copyright (c) 2015-2016 Douglas Christopher Wilson <doug@somethingdoug.com>
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.
1 +# basic-auth
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-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 +Generic basic auth Authorization header field parser for whatever.
10 +
11 +## Installation
12 +
13 +This is a [Node.js](https://nodejs.org/en/) module available through the
14 +[npm registry](https://www.npmjs.com/). Installation is done using the
15 +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
16 +
17 +```
18 +$ npm install basic-auth
19 +```
20 +
21 +## API
22 +
23 +<!-- eslint-disable no-unused-vars -->
24 +
25 +```js
26 +var auth = require('basic-auth')
27 +```
28 +
29 +### auth(req)
30 +
31 +Get the basic auth credentials from the given request. The `Authorization`
32 +header is parsed and if the header is invalid, `undefined` is returned,
33 +otherwise an object with `name` and `pass` properties.
34 +
35 +### auth.parse(string)
36 +
37 +Parse a basic auth authorization header string. This will return an object
38 +with `name` and `pass` properties, or `undefined` if the string is invalid.
39 +
40 +## Example
41 +
42 +Pass a Node.js request object to the module export. If parsing fails
43 +`undefined` is returned, otherwise an object with `.name` and `.pass`.
44 +
45 +<!-- eslint-disable no-unused-vars, no-undef -->
46 +
47 +```js
48 +var auth = require('basic-auth')
49 +var user = auth(req)
50 +// => { name: 'something', pass: 'whatever' }
51 +```
52 +
53 +A header string from any other location can also be parsed with
54 +`auth.parse`, for example a `Proxy-Authorization` header:
55 +
56 +<!-- eslint-disable no-unused-vars, no-undef -->
57 +
58 +```js
59 +var auth = require('basic-auth')
60 +var user = auth.parse(req.getHeader('Proxy-Authorization'))
61 +```
62 +
63 +### With vanilla node.js http server
64 +
65 +```js
66 +var http = require('http')
67 +var auth = require('basic-auth')
68 +
69 +// Create server
70 +var server = http.createServer(function (req, res) {
71 + var credentials = auth(req)
72 +
73 + if (!credentials || credentials.name !== 'john' || credentials.pass !== 'secret') {
74 + res.statusCode = 401
75 + res.setHeader('WWW-Authenticate', 'Basic realm="example"')
76 + res.end('Access denied')
77 + } else {
78 + res.end('Access granted')
79 + }
80 +})
81 +
82 +// Listen
83 +server.listen(3000)
84 +```
85 +
86 +# License
87 +
88 +[MIT](LICENSE)
89 +
90 +[npm-image]: https://img.shields.io/npm/v/basic-auth.svg
91 +[npm-url]: https://npmjs.org/package/basic-auth
92 +[node-version-image]: https://img.shields.io/node/v/basic-auth.svg
93 +[node-version-url]: https://nodejs.org/en/download
94 +[travis-image]: https://img.shields.io/travis/jshttp/basic-auth/master.svg
95 +[travis-url]: https://travis-ci.org/jshttp/basic-auth
96 +[coveralls-image]: https://img.shields.io/coveralls/jshttp/basic-auth/master.svg
97 +[coveralls-url]: https://coveralls.io/r/jshttp/basic-auth?branch=master
98 +[downloads-image]: https://img.shields.io/npm/dm/basic-auth.svg
99 +[downloads-url]: https://npmjs.org/package/basic-auth
1 +/*!
2 + * basic-auth
3 + * Copyright(c) 2013 TJ Holowaychuk
4 + * Copyright(c) 2014 Jonathan Ong
5 + * Copyright(c) 2015-2016 Douglas Christopher Wilson
6 + * MIT Licensed
7 + */
8 +
9 +'use strict'
10 +
11 +/**
12 + * Module dependencies.
13 + * @private
14 + */
15 +
16 +var Buffer = require('safe-buffer').Buffer
17 +
18 +/**
19 + * Module exports.
20 + * @public
21 + */
22 +
23 +module.exports = auth
24 +module.exports.parse = parse
25 +
26 +/**
27 + * RegExp for basic auth credentials
28 + *
29 + * credentials = auth-scheme 1*SP token68
30 + * auth-scheme = "Basic" ; case insensitive
31 + * token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"="
32 + * @private
33 + */
34 +
35 +var CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/
36 +
37 +/**
38 + * RegExp for basic auth user/pass
39 + *
40 + * user-pass = userid ":" password
41 + * userid = *<TEXT excluding ":">
42 + * password = *TEXT
43 + * @private
44 + */
45 +
46 +var USER_PASS_REGEXP = /^([^:]*):(.*)$/
47 +
48 +/**
49 + * Parse the Authorization header field of a request.
50 + *
51 + * @param {object} req
52 + * @return {object} with .name and .pass
53 + * @public
54 + */
55 +
56 +function auth (req) {
57 + if (!req) {
58 + throw new TypeError('argument req is required')
59 + }
60 +
61 + if (typeof req !== 'object') {
62 + throw new TypeError('argument req is required to be an object')
63 + }
64 +
65 + // get header
66 + var header = getAuthorization(req)
67 +
68 + // parse header
69 + return parse(header)
70 +}
71 +
72 +/**
73 + * Decode base64 string.
74 + * @private
75 + */
76 +
77 +function decodeBase64 (str) {
78 + return Buffer.from(str, 'base64').toString()
79 +}
80 +
81 +/**
82 + * Get the Authorization header from request object.
83 + * @private
84 + */
85 +
86 +function getAuthorization (req) {
87 + if (!req.headers || typeof req.headers !== 'object') {
88 + throw new TypeError('argument req is required to have headers property')
89 + }
90 +
91 + return req.headers.authorization
92 +}
93 +
94 +/**
95 + * Parse basic auth to object.
96 + *
97 + * @param {string} string
98 + * @return {object}
99 + * @public
100 + */
101 +
102 +function parse (string) {
103 + if (typeof string !== 'string') {
104 + return undefined
105 + }
106 +
107 + // parse header
108 + var match = CREDENTIALS_REGEXP.exec(string)
109 +
110 + if (!match) {
111 + return undefined
112 + }
113 +
114 + // decode user pass
115 + var userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]))
116 +
117 + if (!userPass) {
118 + return undefined
119 + }
120 +
121 + // return credentials object
122 + return new Credentials(userPass[1], userPass[2])
123 +}
124 +
125 +/**
126 + * Object to represent user credentials.
127 + * @private
128 + */
129 +
130 +function Credentials (name, pass) {
131 + this.name = name
132 + this.pass = pass
133 +}
1 +{
2 + "_from": "basic-auth@~2.0.0",
3 + "_id": "basic-auth@2.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
6 + "_location": "/basic-auth",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "basic-auth@~2.0.0",
12 + "name": "basic-auth",
13 + "escapedName": "basic-auth",
14 + "rawSpec": "~2.0.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~2.0.0"
17 + },
18 + "_requiredBy": [
19 + "/morgan"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
22 + "_shasum": "015db3f353e02e56377755f962742e8981e7bbba",
23 + "_spec": "basic-auth@~2.0.0",
24 + "_where": "/home/ubuntu/OpenSource_Project/node_modules/morgan",
25 + "bugs": {
26 + "url": "https://github.com/jshttp/basic-auth/issues"
27 + },
28 + "bundleDependencies": false,
29 + "dependencies": {
30 + "safe-buffer": "5.1.1"
31 + },
32 + "deprecated": false,
33 + "description": "node.js basic auth parser",
34 + "devDependencies": {
35 + "eslint": "3.19.0",
36 + "eslint-config-standard": "10.2.1",
37 + "eslint-plugin-import": "2.7.0",
38 + "eslint-plugin-markdown": "1.0.0-beta.6",
39 + "eslint-plugin-node": "5.1.1",
40 + "eslint-plugin-promise": "3.5.0",
41 + "eslint-plugin-standard": "3.0.1",
42 + "istanbul": "0.4.5",
43 + "mocha": "2.5.3"
44 + },
45 + "engines": {
46 + "node": ">= 0.8"
47 + },
48 + "files": [
49 + "HISTORY.md",
50 + "LICENSE",
51 + "index.js"
52 + ],
53 + "homepage": "https://github.com/jshttp/basic-auth#readme",
54 + "keywords": [
55 + "basic",
56 + "auth",
57 + "authorization",
58 + "basicauth"
59 + ],
60 + "license": "MIT",
61 + "name": "basic-auth",
62 + "repository": {
63 + "type": "git",
64 + "url": "git+https://github.com/jshttp/basic-auth.git"
65 + },
66 + "scripts": {
67 + "lint": "eslint --plugin markdown --ext js,md .",
68 + "test": "mocha --check-leaks --reporter spec --bail",
69 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
70 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
71 + },
72 + "version": "2.0.0"
73 +}
1 +1.4.3 / 2016-05-26
2 +==================
3 +
4 + * deps: cookie@0.3.1
5 + - perf: use for loop in parse
6 +
7 +1.4.2 / 2016-05-20
8 +==================
9 +
10 + * deps: cookie@0.2.4
11 + - perf: enable strict mode
12 + - perf: use for loop in parse
13 + - perf: use string concatination for serialization
14 +
15 +1.4.1 / 2016-01-11
16 +==================
17 +
18 + * deps: cookie@0.2.3
19 + * perf: enable strict mode
20 +
21 +1.4.0 / 2015-09-18
22 +==================
23 +
24 + * Accept array of secrets in addition to a single secret
25 + * Fix `JSONCookie` to return `undefined` for non-string arguments
26 + * Fix `signedCookie` to return `undefined` for non-string arguments
27 + * deps: cookie@0.2.2
28 +
29 +1.3.5 / 2015-05-19
30 +==================
31 +
32 + * deps: cookie@0.1.3
33 + - Slight optimizations
34 +
35 +1.3.4 / 2015-02-15
36 +==================
37 +
38 + * deps: cookie-signature@1.0.6
39 +
40 +1.3.3 / 2014-09-05
41 +==================
42 +
43 + * deps: cookie-signature@1.0.5
44 +
45 +1.3.2 / 2014-06-26
46 +==================
47 +
48 + * deps: cookie-signature@1.0.4
49 + - fix for timing attacks
50 +
51 +1.3.1 / 2014-06-17
52 +==================
53 +
54 + * actually export `signedCookie`
55 +
56 +1.3.0 / 2014-06-17
57 +==================
58 +
59 + * add `signedCookie` export for single cookie unsigning
60 +
61 +1.2.0 / 2014-06-17
62 +==================
63 +
64 + * export parsing functions
65 + * `req.cookies` and `req.signedCookies` are now plain objects
66 + * slightly faster parsing of many cookies
67 +
68 +1.1.0 / 2014-05-12
69 +==================
70 +
71 + * Support for NodeJS version 0.8
72 + * deps: cookie@0.1.2
73 + - Fix for maxAge == 0
74 + - made compat with expires field
75 + - tweak maxAge NaN error message
76 +
77 +1.0.1 / 2014-02-20
78 +==================
79 +
80 + * add missing dependencies
81 +
82 +1.0.0 / 2014-02-15
83 +==================
84 +
85 + * Genesis from `connect`
1 +(The MIT License)
2 +
3 +Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
4 +Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
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.
1 +# cookie-parser
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-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 +Parse `Cookie` header and populate `req.cookies` with an object keyed by the cookie
10 +names. Optionally you may enable signed cookie support by passing a `secret` string,
11 +which assigns `req.secret` so it may be used by other 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 not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
32 +- `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.
33 + - `decode` a function to decode the value of the cookie
34 +
35 +### cookieParser.JSONCookie(str)
36 +
37 +Parse a cookie value as a JSON cookie. This will return the parsed JSON value if it was a JSON cookie, otherwise it will return the passed value.
38 +
39 +### cookieParser.JSONCookies(cookies)
40 +
41 +Given an object, this will iterate over the keys and call `JSONCookie` on each value. This will return the same object passed in.
42 +
43 +### cookieParser.signedCookie(str, secret)
44 +
45 +Parse a cookie value as a signed cookie. This will return the parsed unsigned value if it was a signed cookie and the signature was valid, otherwise it will return the passed value.
46 +
47 +The `secret` argument can be an array or string. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
48 +
49 +### cookieParser.signedCookies(cookies, secret)
50 +
51 +Given an object, this will iterate over the keys and check if any value is a signed cookie. If it is a signed cookie and the signature is valid, the key will be deleted from the object and added to the new object that is returned.
52 +
53 +The `secret` argument can be an array or string. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
54 +
55 +## Example
56 +
57 +```js
58 +var express = require('express')
59 +var cookieParser = require('cookie-parser')
60 +
61 +var app = express()
62 +app.use(cookieParser())
63 +
64 +app.get('/', function(req, res) {
65 + console.log('Cookies: ', req.cookies)
66 +})
67 +
68 +app.listen(8080)
69 +
70 +// curl command that sends an HTTP request with two cookies
71 +// curl http://127.0.0.1:8080 --cookie "Cho=Kim;Greet=Hello"
72 +```
73 +
74 +### [MIT Licensed](LICENSE)
75 +
76 +[npm-image]: https://img.shields.io/npm/v/cookie-parser.svg
77 +[npm-url]: https://npmjs.org/package/cookie-parser
78 +[node-version-image]: https://img.shields.io/node/v/cookie-parser.svg
79 +[node-version-url]: https://nodejs.org/en/download
80 +[travis-image]: https://img.shields.io/travis/expressjs/cookie-parser/master.svg
81 +[travis-url]: https://travis-ci.org/expressjs/cookie-parser
82 +[coveralls-image]: https://img.shields.io/coveralls/expressjs/cookie-parser/master.svg
83 +[coveralls-url]: https://coveralls.io/r/expressjs/cookie-parser?branch=master
84 +[downloads-image]: https://img.shields.io/npm/dm/cookie-parser.svg
85 +[downloads-url]: https://npmjs.org/package/cookie-parser
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 + return function cookieParser(req, res, next) {
41 + if (req.cookies) {
42 + return next();
43 + }
44 +
45 + var cookies = req.headers.cookie;
46 + var secrets = !secret || Array.isArray(secret)
47 + ? (secret || [])
48 + : [secret];
49 +
50 + req.secret = secrets[0];
51 + req.cookies = Object.create(null);
52 + req.signedCookies = Object.create(null);
53 +
54 + // no cookies
55 + if (!cookies) {
56 + return next();
57 + }
58 +
59 + req.cookies = cookie.parse(cookies, options);
60 +
61 + // parse signed cookies
62 + if (secrets.length !== 0) {
63 + req.signedCookies = signedCookies(req.cookies, secrets);
64 + req.signedCookies = JSONCookies(req.signedCookies);
65 + }
66 +
67 + // parse JSON cookies
68 + req.cookies = JSONCookies(req.cookies);
69 +
70 + next();
71 + };
72 +}
73 +
74 +/**
75 + * Parse JSON cookie string.
76 + *
77 + * @param {String} str
78 + * @return {Object} Parsed object or undefined if not json cookie
79 + * @public
80 + */
81 +
82 +function JSONCookie(str) {
83 + if (typeof str !== 'string' || str.substr(0, 2) !== 'j:') {
84 + return undefined;
85 + }
86 +
87 + try {
88 + return JSON.parse(str.slice(2));
89 + } catch (err) {
90 + return undefined;
91 + }
92 +}
93 +
94 +/**
95 + * Parse JSON cookies.
96 + *
97 + * @param {Object} obj
98 + * @return {Object}
99 + * @public
100 + */
101 +
102 +function JSONCookies(obj) {
103 + var cookies = Object.keys(obj);
104 + var key;
105 + var val;
106 +
107 + for (var i = 0; i < cookies.length; i++) {
108 + key = cookies[i];
109 + val = JSONCookie(obj[key]);
110 +
111 + if (val) {
112 + obj[key] = val;
113 + }
114 + }
115 +
116 + return obj;
117 +}
118 +
119 +/**
120 + * Parse a signed cookie string, return the decoded value.
121 + *
122 + * @param {String} str signed cookie string
123 + * @param {string|array} secret
124 + * @return {String} decoded value
125 + * @public
126 + */
127 +
128 +function signedCookie(str, secret) {
129 + if (typeof str !== 'string') {
130 + return undefined;
131 + }
132 +
133 + if (str.substr(0, 2) !== 's:') {
134 + return str;
135 + }
136 +
137 + var secrets = !secret || Array.isArray(secret)
138 + ? (secret || [])
139 + : [secret];
140 +
141 + for (var i = 0; i < secrets.length; i++) {
142 + var val = signature.unsign(str.slice(2), secrets[i]);
143 +
144 + if (val !== false) {
145 + return val;
146 + }
147 + }
148 +
149 + return false;
150 +}
151 +
152 +/**
153 + * Parse signed cookies, returning an object containing the decoded key/value
154 + * pairs, while removing the signed key from obj.
155 + *
156 + * @param {Object} obj
157 + * @param {string|array} secret
158 + * @return {Object}
159 + * @public
160 + */
161 +
162 +function signedCookies(obj, secret) {
163 + var cookies = Object.keys(obj);
164 + var dec;
165 + var key;
166 + var ret = Object.create(null);
167 + var val;
168 +
169 + for (var i = 0; i < cookies.length; i++) {
170 + key = cookies[i];
171 + val = obj[key];
172 + dec = signedCookie(val, secret);
173 +
174 + if (val !== dec) {
175 + ret[key] = dec;
176 + delete obj[key];
177 + }
178 + }
179 +
180 + return ret;
181 +}
1 +{
2 + "_from": "cookie-parser@~1.4.3",
3 + "_id": "cookie-parser@1.4.3",
4 + "_inBundle": false,
5 + "_integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
6 + "_location": "/cookie-parser",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "cookie-parser@~1.4.3",
12 + "name": "cookie-parser",
13 + "escapedName": "cookie-parser",
14 + "rawSpec": "~1.4.3",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.4.3"
17 + },
18 + "_requiredBy": [
19 + "/"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
22 + "_shasum": "0fe31fa19d000b95f4aadf1f53fdc2b8a203baa5",
23 + "_spec": "cookie-parser@~1.4.3",
24 + "_where": "/home/ubuntu/OpenSource_Project",
25 + "author": {
26 + "name": "TJ Holowaychuk",
27 + "email": "tj@vision-media.ca",
28 + "url": "http://tjholowaychuk.com"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/expressjs/cookie-parser/issues"
32 + },
33 + "bundleDependencies": false,
34 + "contributors": [
35 + {
36 + "name": "Douglas Christopher Wilson",
37 + "email": "doug@somethingdoug.com"
38 + }
39 + ],
40 + "dependencies": {
41 + "cookie": "0.3.1",
42 + "cookie-signature": "1.0.6"
43 + },
44 + "deprecated": false,
45 + "description": "cookie parsing with signatures",
46 + "devDependencies": {
47 + "istanbul": "0.4.3",
48 + "mocha": "2.5.3",
49 + "supertest": "1.1.0"
50 + },
51 + "engines": {
52 + "node": ">= 0.8.0"
53 + },
54 + "files": [
55 + "LICENSE",
56 + "HISTORY.md",
57 + "index.js"
58 + ],
59 + "homepage": "https://github.com/expressjs/cookie-parser#readme",
60 + "keywords": [
61 + "cookie",
62 + "middleware"
63 + ],
64 + "license": "MIT",
65 + "name": "cookie-parser",
66 + "repository": {
67 + "type": "git",
68 + "url": "git+https://github.com/expressjs/cookie-parser.git"
69 + },
70 + "scripts": {
71 + "test": "mocha --reporter spec --bail --check-leaks test/",
72 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
73 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
74 + },
75 + "version": "1.4.3"
76 +}
1 +var fs = require('fs');
2 +var execSync = require('child_process').execSync;
3 +var exec = function (cmd) {
4 + execSync(cmd, {stdio: 'inherit'});
5 +};
6 +
7 +/* global jake, task, desc, publishTask */
8 +
9 +task('build', ['lint', 'clean', 'browserify', 'minify'], function () {
10 + console.log('Build completed.');
11 +});
12 +
13 +desc('Cleans browerified/minified files and package files');
14 +task('clean', ['clobber'], function () {
15 + jake.rmRf('./ejs.js');
16 + jake.rmRf('./ejs.min.js');
17 + console.log('Cleaned up compiled files.');
18 +});
19 +
20 +desc('Lints the source code');
21 +task('lint', function () {
22 + exec('./node_modules/.bin/eslint \"**/*.js\" Jakefile');
23 + console.log('Linting completed.');
24 +});
25 +
26 +task('browserify', function () {
27 + exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js');
28 + console.log('Browserification completed.');
29 +});
30 +
31 +task('minify', function () {
32 + exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js');
33 + console.log('Minification completed.');
34 +});
35 +
36 +task('doc', function (dev) {
37 + jake.rmRf('out');
38 + var p = dev ? '-p' : '';
39 + exec('./node_modules/.bin/jsdoc ' + p + ' -c jsdoc.json lib/* docs/jsdoc/*');
40 + console.log('Documentation generated.');
41 +});
42 +
43 +task('docPublish', ['doc'], function () {
44 + fs.writeFileSync('out/CNAME', 'api.ejs.co');
45 + console.log('Pushing docs to gh-pages...');
46 + exec('./node_modules/.bin/git-directory-deploy --directory out/');
47 + console.log('Docs published to gh-pages.');
48 +});
49 +
50 +task('test', ['lint'], function () {
51 + exec('./node_modules/.bin/mocha');
52 +});
53 +
54 +publishTask('ejs', ['build'], function () {
55 + this.packageFiles.include([
56 + 'Jakefile',
57 + 'README.md',
58 + 'LICENSE',
59 + 'package.json',
60 + 'ejs.js',
61 + 'ejs.min.js',
62 + 'lib/**'
63 + ]);
64 +});
65 +
66 +jake.Task.publish.on('complete', function () {
67 + console.log('Updating hosted docs...');
68 + console.log('If this fails, run jake docPublish to re-try.');
69 + jake.Task.docPublish.invoke();
70 +});
This diff is collapsed. Click to expand it.
1 +# EJS
2 +
3 +Embedded JavaScript templates
4 +
5 +[![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs)
6 +[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs?type=dev)
7 +[![Known Vulnerabilities](https://snyk.io/test/npm/ejs/badge.svg?style=flat-square)](https://snyk.io/test/npm/ejs)
8 +
9 +## Installation
10 +
11 +```bash
12 +$ npm install ejs
13 +```
14 +
15 +## Features
16 +
17 + * Control flow with `<% %>`
18 + * Escaped output with `<%= %>` (escape function configurable)
19 + * Unescaped raw output with `<%- %>`
20 + * Newline-trim mode ('newline slurping') with `-%>` ending tag
21 + * Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>`
22 + * Custom delimiters (e.g., use `<? ?>` instead of `<% %>`)
23 + * Includes
24 + * Client-side support
25 + * Static caching of intermediate JavaScript
26 + * Static caching of templates
27 + * Complies with the [Express](http://expressjs.com) view system
28 +
29 +## Example
30 +
31 +```html
32 +<% if (user) { %>
33 + <h2><%= user.name %></h2>
34 +<% } %>
35 +```
36 +
37 +Try EJS online at: https://ionicabizau.github.io/ejs-playground/.
38 +
39 +## Usage
40 +
41 +```javascript
42 +var template = ejs.compile(str, options);
43 +template(data);
44 +// => Rendered HTML string
45 +
46 +ejs.render(str, data, options);
47 +// => Rendered HTML string
48 +
49 +ejs.renderFile(filename, data, options, function(err, str){
50 + // str => Rendered HTML string
51 +});
52 +```
53 +
54 +It is also possible to use `ejs.render(dataAndOptions);` where you pass
55 +everything in a single object. In that case, you'll end up with local variables
56 +for all the passed options. However, be aware that your code could break if we
57 +add an option with the same name as one of your data object's properties.
58 +Therefore, we do not recommend using this shortcut.
59 +
60 +## Options
61 +
62 + - `cache` Compiled functions are cached, requires `filename`
63 + - `filename` The name of the file being rendered. Not required if you
64 + are using `renderFile()`. Used by `cache` to key caches, and for includes.
65 + - `root` Set project root for includes with an absolute path (/file.ejs).
66 + - `context` Function execution context
67 + - `compileDebug` When `false` no debug instrumentation is compiled
68 + - `client` When `true`, compiles a function that can be rendered
69 + in the browser without needing to load the EJS Runtime
70 + ([ejs.min.js](https://github.com/mde/ejs/releases/latest)).
71 + - `delimiter` Character to use with angle brackets for open/close
72 + - `debug` Output generated function body
73 + - `strict` When set to `true`, generated function is in strict mode
74 + - `_with` Whether or not to use `with() {}` constructs. If `false` then the locals will be stored in the `locals` object. Set to `false` in strict mode.
75 + - `localsName` Name to use for the object storing local variables when not using `with` Defaults to `locals`
76 + - `rmWhitespace` Remove all safe-to-remove whitespace, including leading
77 + and trailing whitespace. It also enables a safer version of `-%>` line
78 + slurping for all scriptlet tags (it does not strip new lines of tags in
79 + the middle of a line).
80 + - `escape` The escaping function used with `<%=` construct. It is
81 + used in rendering and is `.toString()`ed in the generation of client functions. (By default escapes XML).
82 +
83 +This project uses [JSDoc](http://usejsdoc.org/). For the full public API
84 +documentation, clone the repository and run `npm run doc`. This will run JSDoc
85 +with the proper options and output the documentation to `out/`. If you want
86 +the both the public & private API docs, run `npm run devdoc` instead.
87 +
88 +## Tags
89 +
90 + - `<%` 'Scriptlet' tag, for control-flow, no output
91 + - `<%_` 'Whitespace Slurping' Scriptlet tag, strips all whitespace before it
92 + - `<%=` Outputs the value into the template (escaped)
93 + - `<%-` Outputs the unescaped value into the template
94 + - `<%#` Comment tag, no execution, no output
95 + - `<%%` Outputs a literal '<%'
96 + - `%%>` Outputs a literal '%>'
97 + - `%>` Plain ending tag
98 + - `-%>` Trim-mode ('newline slurp') tag, trims following newline
99 + - `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it
100 +
101 +For the full syntax documentation, please see [docs/syntax.md](https://github.com/mde/ejs/blob/master/docs/syntax.md).
102 +
103 +## Includes
104 +
105 +Includes either have to be an absolute path, or, if not, are assumed as
106 +relative to the template with the `include` call. For example if you are
107 +including `./views/user/show.ejs` from `./views/users.ejs` you would
108 +use `<%- include('user/show') %>`.
109 +
110 +You must specify the `filename` option for the template with the `include`
111 +call unless you are using `renderFile()`.
112 +
113 +You'll likely want to use the raw output tag (`<%-`) with your include to avoid
114 +double-escaping the HTML output.
115 +
116 +```html
117 +<ul>
118 + <% users.forEach(function(user){ %>
119 + <%- include('user/show', {user: user}) %>
120 + <% }); %>
121 +</ul>
122 +```
123 +
124 +Includes are inserted at runtime, so you can use variables for the path in the
125 +`include` call (for example `<%- include(somePath) %>`). Variables in your
126 +top-level data object are available to all your includes, but local variables
127 +need to be passed down.
128 +
129 +NOTE: Include preprocessor directives (`<% include user/show %>`) are
130 +still supported.
131 +
132 +## Custom delimiters
133 +
134 +Custom delimiters can be applied on a per-template basis, or globally:
135 +
136 +```javascript
137 +var ejs = require('ejs'),
138 + users = ['geddy', 'neil', 'alex'];
139 +
140 +// Just one template
141 +ejs.render('<?= users.join(" | "); ?>', {users: users}, {delimiter: '?'});
142 +// => 'geddy | neil | alex'
143 +
144 +// Or globally
145 +ejs.delimiter = '$';
146 +ejs.render('<$= users.join(" | "); $>', {users: users});
147 +// => 'geddy | neil | alex'
148 +```
149 +
150 +## Caching
151 +
152 +EJS ships with a basic in-process cache for caching the intermediate JavaScript
153 +functions used to render templates. It's easy to plug in LRU caching using
154 +Node's `lru-cache` library:
155 +
156 +```javascript
157 +var ejs = require('ejs')
158 + , LRU = require('lru-cache');
159 +ejs.cache = LRU(100); // LRU cache with 100-item limit
160 +```
161 +
162 +If you want to clear the EJS cache, call `ejs.clearCache`. If you're using the
163 +LRU cache and need a different limit, simple reset `ejs.cache` to a new instance
164 +of the LRU.
165 +
166 +## Custom FileLoader
167 +
168 +The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader.
169 +
170 +```javascript
171 +var ejs = require('ejs');
172 +var myFileLoad = function (filePath) {
173 + return 'myFileLoad: ' + fs.readFileSync(filePath);
174 +};
175 +
176 +ejs.fileLoader = myFileLoad;
177 +```
178 +
179 +With this feature, you can preprocess the template before reading it.
180 +
181 +## Layouts
182 +
183 +EJS does not specifically support blocks, but layouts can be implemented by
184 +including headers and footers, like so:
185 +
186 +
187 +```html
188 +<%- include('header') -%>
189 +<h1>
190 + Title
191 +</h1>
192 +<p>
193 + My page
194 +</p>
195 +<%- include('footer') -%>
196 +```
197 +
198 +## Client-side support
199 +
200 +Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download
201 +`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning
202 +the repository and running `jake build` (or `$(npm bin)/jake build` if jake is
203 +not installed globally).
204 +
205 +Include one of these files on your page, and `ejs` should be available globally.
206 +
207 +### Example
208 +
209 +```html
210 +<div id="output"></div>
211 +<script src="ejs.min.js"></script>
212 +<script>
213 + var people = ['geddy', 'neil', 'alex'],
214 + html = ejs.render('<%= people.join(", "); %>', {people: people});
215 + // With jQuery:
216 + $('#output').html(html);
217 + // Vanilla JS:
218 + document.getElementById('output').innerHTML = html;
219 +</script>
220 +```
221 +
222 +### Caveats
223 +
224 +Most of EJS will work as expected; however, there are a few things to note:
225 +
226 +1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work.
227 +2. For the same reason, `include`s do not work unless you use an `IncludeCallback`. Here is an example:
228 + ```javascript
229 + var str = "Hello <%= include('file', {person: 'John'}); %>",
230 + fn = ejs.compile(str, {client: true});
231 +
232 + fn(data, null, function(path, d){ // IncludeCallback
233 + // path -> 'file'
234 + // d -> {person: 'John'}
235 + // Put your code here
236 + // Return the contents of file as a string
237 + }); // returns rendered string
238 + ```
239 +
240 +## Related projects
241 +
242 +There are a number of implementations of EJS:
243 +
244 + * TJ's implementation, the v1 of this library: https://github.com/tj/ejs
245 + * Jupiter Consulting's EJS: http://www.embeddedjs.com/
246 + * EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/
247 + * Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs
248 + * Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript
249 +
250 +## License
251 +
252 +Licensed under the Apache License, Version 2.0
253 +(<http://www.apache.org/licenses/LICENSE-2.0>)
254 +
255 +- - -
256 +EJS Embedded JavaScript templates copyright 2112
257 +mde@fleegix.org.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +/*
2 + * EJS Embedded JavaScript templates
3 + * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
4 + *
5 + * Licensed under the Apache License, Version 2.0 (the "License");
6 + * you may not use this file except in compliance with the License.
7 + * You may obtain a copy of the License at
8 + *
9 + * http://www.apache.org/licenses/LICENSE-2.0
10 + *
11 + * Unless required by applicable law or agreed to in writing, software
12 + * distributed under the License is distributed on an "AS IS" BASIS,
13 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + * See the License for the specific language governing permissions and
15 + * limitations under the License.
16 + *
17 +*/
18 +
19 +/**
20 + * Private utility functions
21 + * @module utils
22 + * @private
23 + */
24 +
25 +'use strict';
26 +
27 +var regExpChars = /[|\\{}()[\]^$+*?.]/g;
28 +
29 +/**
30 + * Escape characters reserved in regular expressions.
31 + *
32 + * If `string` is `undefined` or `null`, the empty string is returned.
33 + *
34 + * @param {String} string Input string
35 + * @return {String} Escaped string
36 + * @static
37 + * @private
38 + */
39 +exports.escapeRegExpChars = function (string) {
40 + // istanbul ignore if
41 + if (!string) {
42 + return '';
43 + }
44 + return String(string).replace(regExpChars, '\\$&');
45 +};
46 +
47 +var _ENCODE_HTML_RULES = {
48 + '&': '&amp;',
49 + '<': '&lt;',
50 + '>': '&gt;',
51 + '"': '&#34;',
52 + "'": '&#39;'
53 +};
54 +var _MATCH_HTML = /[&<>\'"]/g;
55 +
56 +function encode_char(c) {
57 + return _ENCODE_HTML_RULES[c] || c;
58 +}
59 +
60 +/**
61 + * Stringified version of constants used by {@link module:utils.escapeXML}.
62 + *
63 + * It is used in the process of generating {@link ClientFunction}s.
64 + *
65 + * @readonly
66 + * @type {String}
67 + */
68 +
69 +var escapeFuncStr =
70 + 'var _ENCODE_HTML_RULES = {\n'
71 ++ ' "&": "&amp;"\n'
72 ++ ' , "<": "&lt;"\n'
73 ++ ' , ">": "&gt;"\n'
74 ++ ' , \'"\': "&#34;"\n'
75 ++ ' , "\'": "&#39;"\n'
76 ++ ' }\n'
77 ++ ' , _MATCH_HTML = /[&<>\'"]/g;\n'
78 ++ 'function encode_char(c) {\n'
79 ++ ' return _ENCODE_HTML_RULES[c] || c;\n'
80 ++ '};\n';
81 +
82 +/**
83 + * Escape characters reserved in XML.
84 + *
85 + * If `markup` is `undefined` or `null`, the empty string is returned.
86 + *
87 + * @implements {EscapeCallback}
88 + * @param {String} markup Input string
89 + * @return {String} Escaped string
90 + * @static
91 + * @private
92 + */
93 +
94 +exports.escapeXML = function (markup) {
95 + return markup == undefined
96 + ? ''
97 + : String(markup)
98 + .replace(_MATCH_HTML, encode_char);
99 +};
100 +exports.escapeXML.toString = function () {
101 + return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
102 +};
103 +
104 +/**
105 + * Naive copy of properties from one object to another.
106 + * Does not recurse into non-scalar properties
107 + * Does not check to see if the property has a value before copying
108 + *
109 + * @param {Object} to Destination object
110 + * @param {Object} from Source object
111 + * @return {Object} Destination object
112 + * @static
113 + * @private
114 + */
115 +exports.shallowCopy = function (to, from) {
116 + from = from || {};
117 + for (var p in from) {
118 + to[p] = from[p];
119 + }
120 + return to;
121 +};
122 +
123 +/**
124 + * Naive copy of a list of key names, from one object to another.
125 + * Only copies property if it is actually defined
126 + * Does not recurse into non-scalar properties
127 + *
128 + * @param {Object} to Destination object
129 + * @param {Object} from Source object
130 + * @param {Array} list List of properties to copy
131 + * @return {Object} Destination object
132 + * @static
133 + * @private
134 + */
135 +exports.shallowCopyFromList = function (to, from, list) {
136 + for (var i = 0; i < list.length; i++) {
137 + var p = list[i];
138 + if (typeof from[p] != 'undefined') {
139 + to[p] = from[p];
140 + }
141 + }
142 + return to;
143 +};
144 +
145 +/**
146 + * Simple in-process cache implementation. Does not implement limits of any
147 + * sort.
148 + *
149 + * @implements Cache
150 + * @static
151 + * @private
152 + */
153 +exports.cache = {
154 + _data: {},
155 + set: function (key, val) {
156 + this._data[key] = val;
157 + },
158 + get: function (key) {
159 + return this._data[key];
160 + },
161 + reset: function () {
162 + this._data = {};
163 + }
164 +};
1 +{
2 + "_from": "ejs@~2.5.7",
3 + "_id": "ejs@2.5.7",
4 + "_inBundle": false,
5 + "_integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=",
6 + "_location": "/ejs",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "ejs@~2.5.7",
12 + "name": "ejs",
13 + "escapedName": "ejs",
14 + "rawSpec": "~2.5.7",
15 + "saveSpec": null,
16 + "fetchSpec": "~2.5.7"
17 + },
18 + "_requiredBy": [
19 + "/"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
22 + "_shasum": "cc872c168880ae3c7189762fd5ffc00896c9518a",
23 + "_spec": "ejs@~2.5.7",
24 + "_where": "/home/ubuntu/OpenSource_Project",
25 + "author": {
26 + "name": "Matthew Eernisse",
27 + "email": "mde@fleegix.org",
28 + "url": "http://fleegix.org"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/mde/ejs/issues"
32 + },
33 + "bundleDependencies": false,
34 + "contributors": [
35 + {
36 + "name": "Timothy Gu",
37 + "email": "timothygu99@gmail.com",
38 + "url": "https://timothygu.github.io"
39 + }
40 + ],
41 + "dependencies": {},
42 + "deprecated": false,
43 + "description": "Embedded JavaScript templates",
44 + "devDependencies": {
45 + "browserify": "^13.0.1",
46 + "eslint": "^3.0.0",
47 + "git-directory-deploy": "^1.5.1",
48 + "istanbul": "~0.4.3",
49 + "jake": "^8.0.0",
50 + "jsdoc": "^3.4.0",
51 + "lru-cache": "^4.0.1",
52 + "mocha": "^3.0.2",
53 + "uglify-js": "^2.6.2"
54 + },
55 + "engines": {
56 + "node": ">=0.10.0"
57 + },
58 + "homepage": "https://github.com/mde/ejs",
59 + "keywords": [
60 + "template",
61 + "engine",
62 + "ejs"
63 + ],
64 + "license": "Apache-2.0",
65 + "main": "./lib/ejs.js",
66 + "name": "ejs",
67 + "repository": {
68 + "type": "git",
69 + "url": "git://github.com/mde/ejs.git"
70 + },
71 + "scripts": {
72 + "coverage": "istanbul cover node_modules/mocha/bin/_mocha",
73 + "devdoc": "jake doc[dev]",
74 + "doc": "jake doc",
75 + "lint": "eslint \"**/*.js\" Jakefile",
76 + "test": "jake test"
77 + },
78 + "version": "2.5.7"
79 +}
1 +1.9.0 / 2017-09-26
2 +==================
3 +
4 + * Use `res.headersSent` when available
5 + * deps: basic-auth@~2.0.0
6 + - Use `safe-buffer` for improved Buffer API
7 + * deps: debug@2.6.9
8 + * deps: depd@~1.1.1
9 + - Remove unnecessary `Buffer` loading
10 +
11 +1.8.2 / 2017-05-23
12 +==================
13 +
14 + * deps: debug@2.6.8
15 + - Fix `DEBUG_MAX_ARRAY_LENGTH`
16 + - deps: ms@2.0.0
17 +
18 +1.8.1 / 2017-02-04
19 +==================
20 +
21 + * deps: debug@2.6.1
22 + - Fix deprecation messages in WebStorm and other editors
23 + - Undeprecate `DEBUG_FD` set to `1` or `2`
24 +
25 +1.8.0 / 2017-02-04
26 +==================
27 +
28 + * Fix sending unnecessary `undefined` argument to token functions
29 + * deps: basic-auth@~1.1.0
30 + * deps: debug@2.6.0
31 + - Allow colors in workers
32 + - Deprecated `DEBUG_FD` environment variable
33 + - Fix error when running under React Native
34 + - Use same color for same namespace
35 + - deps: ms@0.7.2
36 + * perf: enable strict mode in compiled functions
37 +
38 +1.7.0 / 2016-02-18
39 +==================
40 +
41 + * Add `digits` argument to `response-time` token
42 + * deps: depd@~1.1.0
43 + - Enable strict mode in more places
44 + - Support web browser loading
45 + * deps: on-headers@~1.0.1
46 + - perf: enable strict mode
47 +
48 +1.6.1 / 2015-07-03
49 +==================
50 +
51 + * deps: basic-auth@~1.0.3
52 +
53 +1.6.0 / 2015-06-12
54 +==================
55 +
56 + * Add `morgan.compile(format)` export
57 + * Do not color 1xx status codes in `dev` format
58 + * Fix `response-time` token to not include response latency
59 + * Fix `status` token incorrectly displaying before response in `dev` format
60 + * Fix token return values to be `undefined` or a string
61 + * Improve representation of multiple headers in `req` and `res` tokens
62 + * Use `res.getHeader` in `res` token
63 + * deps: basic-auth@~1.0.2
64 + - perf: enable strict mode
65 + - perf: hoist regular expression
66 + - perf: parse with regular expressions
67 + - perf: remove argument reassignment
68 + * deps: on-finished@~2.3.0
69 + - Add defined behavior for HTTP `CONNECT` requests
70 + - Add defined behavior for HTTP `Upgrade` requests
71 + - deps: ee-first@1.1.1
72 + * pref: enable strict mode
73 + * pref: reduce function closure scopes
74 + * pref: remove dynamic compile on every request for `dev` format
75 + * pref: remove an argument reassignment
76 + * pref: skip function call without `skip` option
77 +
78 +1.5.3 / 2015-05-10
79 +==================
80 +
81 + * deps: basic-auth@~1.0.1
82 + * deps: debug@~2.2.0
83 + - deps: ms@0.7.1
84 + * deps: depd@~1.0.1
85 + * deps: on-finished@~2.2.1
86 + - Fix `isFinished(req)` when data buffered
87 +
88 +1.5.2 / 2015-03-15
89 +==================
90 +
91 + * deps: debug@~2.1.3
92 + - Fix high intensity foreground color for bold
93 + - deps: ms@0.7.0
94 +
95 +1.5.1 / 2014-12-31
96 +==================
97 +
98 + * deps: debug@~2.1.1
99 + * deps: on-finished@~2.2.0
100 +
101 +1.5.0 / 2014-11-06
102 +==================
103 +
104 + * Add multiple date formats
105 + - `clf` for the common log format
106 + - `iso` for the common ISO 8601 date time format
107 + - `web` for the common RFC 1123 date time format
108 + * Deprecate `buffer` option
109 + * Fix date format in `common` and `combined` formats
110 + * Fix token arguments to accept values with `"`
111 +
112 +1.4.1 / 2014-10-22
113 +==================
114 +
115 + * deps: on-finished@~2.1.1
116 + - Fix handling of pipelined requests
117 +
118 +1.4.0 / 2014-10-16
119 +==================
120 +
121 + * Add `debug` messages
122 + * deps: depd@~1.0.0
123 +
124 +1.3.2 / 2014-09-27
125 +==================
126 +
127 + * Fix `req.ip` integration when `immediate: false`
128 +
129 +1.3.1 / 2014-09-14
130 +==================
131 +
132 + * Remove un-used `bytes` dependency
133 + * deps: depd@0.4.5
134 +
135 +1.3.0 / 2014-09-01
136 +==================
137 +
138 + * Assert if `format` is not a function or string
139 +
140 +1.2.3 / 2014-08-16
141 +==================
142 +
143 + * deps: on-finished@2.1.0
144 +
145 +1.2.2 / 2014-07-27
146 +==================
147 +
148 + * deps: depd@0.4.4
149 + - Work-around v8 generating empty stack traces
150 +
151 +1.2.1 / 2014-07-26
152 +==================
153 +
154 + * deps: depd@0.4.3
155 + - Fix exception when global `Error.stackTraceLimit` is too low
156 +
157 +1.2.0 / 2014-07-19
158 +==================
159 +
160 + * Add `:remote-user` token
161 + * Add `combined` log format
162 + * Add `common` log format
163 + * Add `morgan(format, options)` function signature
164 + * Deprecate `default` format -- use `combined` format instead
165 + * Deprecate not providing a format
166 + * Remove non-standard grey color from `dev` format
167 +
168 +1.1.1 / 2014-05-20
169 +==================
170 +
171 + * simplify method to get remote address
172 +
173 +1.1.0 / 2014-05-18
174 +==================
175 +
176 + * "dev" format will use same tokens as other formats
177 + * `:response-time` token is now empty when immediate used
178 + * `:response-time` token is now monotonic
179 + * `:response-time` token has precision to 1 μs
180 + * fix `:status` + immediate output in node.js 0.8
181 + * improve `buffer` option to prevent indefinite event loop holding
182 + * deps: bytes@1.0.0
183 + - add negative support
184 +
185 +1.0.1 / 2014-05-04
186 +==================
187 +
188 + * Make buffer unique per morgan instance
189 + * deps: bytes@0.3.0
190 + * added terabyte support
191 +
192 +1.0.0 / 2014-02-08
193 +==================
194 +
195 + * Initial release
1 +(The MIT License)
2 +
3 +Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
4 +Copyright (c) 2014-2017 Douglas Christopher Wilson <doug@somethingdoug.com>
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.
This diff is collapsed. Click to expand it.
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 = format.replace(/"/g, '\\"')
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 +}
1 +{
2 + "_from": "morgan@~1.9.0",
3 + "_id": "morgan@1.9.0",
4 + "_inBundle": false,
5 + "_integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
6 + "_location": "/morgan",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "morgan@~1.9.0",
12 + "name": "morgan",
13 + "escapedName": "morgan",
14 + "rawSpec": "~1.9.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.9.0"
17 + },
18 + "_requiredBy": [
19 + "/"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
22 + "_shasum": "d01fa6c65859b76fcf31b3cb53a3821a311d8051",
23 + "_spec": "morgan@~1.9.0",
24 + "_where": "/home/ubuntu/OpenSource_Project",
25 + "bugs": {
26 + "url": "https://github.com/expressjs/morgan/issues"
27 + },
28 + "bundleDependencies": false,
29 + "contributors": [
30 + {
31 + "name": "Douglas Christopher Wilson",
32 + "email": "doug@somethingdoug.com"
33 + },
34 + {
35 + "name": "Jonathan Ong",
36 + "email": "me@jongleberry.com",
37 + "url": "http://jongleberry.com"
38 + }
39 + ],
40 + "dependencies": {
41 + "basic-auth": "~2.0.0",
42 + "debug": "2.6.9",
43 + "depd": "~1.1.1",
44 + "on-finished": "~2.3.0",
45 + "on-headers": "~1.0.1"
46 + },
47 + "deprecated": false,
48 + "description": "HTTP request logger middleware for node.js",
49 + "devDependencies": {
50 + "eslint": "3.19.0",
51 + "eslint-config-standard": "10.2.1",
52 + "eslint-plugin-import": "2.7.0",
53 + "eslint-plugin-markdown": "1.0.0-beta.6",
54 + "eslint-plugin-node": "5.1.1",
55 + "eslint-plugin-promise": "3.5.0",
56 + "eslint-plugin-standard": "3.0.1",
57 + "istanbul": "0.4.5",
58 + "mocha": "2.5.3",
59 + "split": "1.0.1",
60 + "supertest": "1.1.0"
61 + },
62 + "engines": {
63 + "node": ">= 0.8.0"
64 + },
65 + "files": [
66 + "LICENSE",
67 + "HISTORY.md",
68 + "README.md",
69 + "index.js"
70 + ],
71 + "homepage": "https://github.com/expressjs/morgan#readme",
72 + "keywords": [
73 + "express",
74 + "http",
75 + "logger",
76 + "middleware"
77 + ],
78 + "license": "MIT",
79 + "name": "morgan",
80 + "repository": {
81 + "type": "git",
82 + "url": "git+https://github.com/expressjs/morgan.git"
83 + },
84 + "scripts": {
85 + "lint": "eslint --plugin markdown --ext js,md .",
86 + "test": "mocha --check-leaks --reporter spec --bail",
87 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot",
88 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec"
89 + },
90 + "version": "1.9.0"
91 +}
1 +1.0.1 / 2015-09-29
2 +==================
3 +
4 + * perf: enable strict mode
5 +
6 +1.0.0 / 2014-08-10
7 +==================
8 +
9 + * Honor `res.statusCode` change in `listener`
10 + * Move to `jshttp` orgainzation
11 + * Prevent `arguments`-related de-opt
12 +
13 +0.0.0 / 2014-05-13
14 +==================
15 +
16 + * Initial implementation
1 +(The MIT License)
2 +
3 +Copyright (c) 2014 Douglas Christopher Wilson
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining
6 +a copy of this software and associated documentation files (the
7 +'Software'), to deal in the Software without restriction, including
8 +without limitation the rights to use, copy, modify, merge, publish,
9 +distribute, sublicense, and/or sell copies of the Software, and to
10 +permit persons to whom the Software is furnished to do so, subject to
11 +the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be
14 +included in all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# on-headers
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-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 +Execute a listener when a response is about to write headers.
10 +
11 +## Installation
12 +
13 +```sh
14 +$ npm install on-headers
15 +```
16 +
17 +## API
18 +
19 +```js
20 +var onHeaders = require('on-headers')
21 +```
22 +
23 +### onHeaders(res, listener)
24 +
25 +This will add the listener `listener` to fire when headers are emitted for `res`.
26 +The listener is passed the `response` object as it's context (`this`). Headers are
27 +considered to be emitted only once, right before they are sent to the client.
28 +
29 +When this is called multiple times on the same `res`, the `listener`s are fired
30 +in the reverse order they were added.
31 +
32 +## Examples
33 +
34 +```js
35 +var http = require('http')
36 +var onHeaders = require('on-headers')
37 +
38 +http
39 +.createServer(onRequest)
40 +.listen(3000)
41 +
42 +function addPoweredBy() {
43 + // set if not set by end of request
44 + if (!this.getHeader('X-Powered-By')) {
45 + this.setHeader('X-Powered-By', 'Node.js')
46 + }
47 +}
48 +
49 +function onRequest(req, res) {
50 + onHeaders(res, addPoweredBy)
51 +
52 + res.setHeader('Content-Type', 'text/plain')
53 + res.end('hello!')
54 +}
55 +```
56 +
57 +## Testing
58 +
59 +```sh
60 +$ npm test
61 +```
62 +
63 +## License
64 +
65 +[MIT](LICENSE)
66 +
67 +[npm-image]: https://img.shields.io/npm/v/on-headers.svg
68 +[npm-url]: https://npmjs.org/package/on-headers
69 +[node-version-image]: https://img.shields.io/node/v/on-headers.svg
70 +[node-version-url]: http://nodejs.org/download/
71 +[travis-image]: https://img.shields.io/travis/jshttp/on-headers/master.svg
72 +[travis-url]: https://travis-ci.org/jshttp/on-headers
73 +[coveralls-image]: https://img.shields.io/coveralls/jshttp/on-headers/master.svg
74 +[coveralls-url]: https://coveralls.io/r/jshttp/on-headers?branch=master
75 +[downloads-image]: https://img.shields.io/npm/dm/on-headers.svg
76 +[downloads-url]: https://npmjs.org/package/on-headers
1 +/*!
2 + * on-headers
3 + * Copyright(c) 2014 Douglas Christopher Wilson
4 + * MIT Licensed
5 + */
6 +
7 +'use strict'
8 +
9 +/**
10 + * Reference to Array slice.
11 + */
12 +
13 +var slice = Array.prototype.slice
14 +
15 +/**
16 + * Execute a listener when a response is about to write headers.
17 + *
18 + * @param {Object} res
19 + * @return {Function} listener
20 + * @api public
21 + */
22 +
23 +module.exports = function onHeaders(res, listener) {
24 + if (!res) {
25 + throw new TypeError('argument res is required')
26 + }
27 +
28 + if (typeof listener !== 'function') {
29 + throw new TypeError('argument listener must be a function')
30 + }
31 +
32 + res.writeHead = createWriteHead(res.writeHead, listener)
33 +}
34 +
35 +function createWriteHead(prevWriteHead, listener) {
36 + var fired = false;
37 +
38 + // return function with core name and argument list
39 + return function writeHead(statusCode) {
40 + // set headers from arguments
41 + var args = setWriteHeadHeaders.apply(this, arguments);
42 +
43 + // fire listener
44 + if (!fired) {
45 + fired = true
46 + listener.call(this)
47 +
48 + // pass-along an updated status code
49 + if (typeof args[0] === 'number' && this.statusCode !== args[0]) {
50 + args[0] = this.statusCode
51 + args.length = 1
52 + }
53 + }
54 +
55 + prevWriteHead.apply(this, args);
56 + }
57 +}
58 +
59 +function setWriteHeadHeaders(statusCode) {
60 + var length = arguments.length
61 + var headerIndex = length > 1 && typeof arguments[1] === 'string'
62 + ? 2
63 + : 1
64 +
65 + var headers = length >= headerIndex + 1
66 + ? arguments[headerIndex]
67 + : undefined
68 +
69 + this.statusCode = statusCode
70 +
71 + // the following block is from node.js core
72 + if (Array.isArray(headers)) {
73 + // handle array case
74 + for (var i = 0, len = headers.length; i < len; ++i) {
75 + this.setHeader(headers[i][0], headers[i][1])
76 + }
77 + } else if (headers) {
78 + // handle object case
79 + var keys = Object.keys(headers)
80 + for (var i = 0; i < keys.length; i++) {
81 + var k = keys[i]
82 + if (k) this.setHeader(k, headers[k])
83 + }
84 + }
85 +
86 + // copy leading arguments
87 + var args = new Array(Math.min(length, headerIndex))
88 + for (var i = 0; i < args.length; i++) {
89 + args[i] = arguments[i]
90 + }
91 +
92 + return args
93 +}
1 +{
2 + "_from": "on-headers@~1.0.1",
3 + "_id": "on-headers@1.0.1",
4 + "_inBundle": false,
5 + "_integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
6 + "_location": "/on-headers",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "on-headers@~1.0.1",
12 + "name": "on-headers",
13 + "escapedName": "on-headers",
14 + "rawSpec": "~1.0.1",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.0.1"
17 + },
18 + "_requiredBy": [
19 + "/morgan"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
22 + "_shasum": "928f5d0f470d49342651ea6794b0857c100693f7",
23 + "_spec": "on-headers@~1.0.1",
24 + "_where": "/home/ubuntu/OpenSource_Project/node_modules/morgan",
25 + "author": {
26 + "name": "Douglas Christopher Wilson",
27 + "email": "doug@somethingdoug.com"
28 + },
29 + "bugs": {
30 + "url": "https://github.com/jshttp/on-headers/issues"
31 + },
32 + "bundleDependencies": false,
33 + "dependencies": {},
34 + "deprecated": false,
35 + "description": "Execute a listener when a response is about to write headers",
36 + "devDependencies": {
37 + "istanbul": "0.3.21",
38 + "mocha": "2.3.3",
39 + "supertest": "1.1.0"
40 + },
41 + "engines": {
42 + "node": ">= 0.8"
43 + },
44 + "files": [
45 + "LICENSE",
46 + "HISTORY.md",
47 + "README.md",
48 + "index.js"
49 + ],
50 + "homepage": "https://github.com/jshttp/on-headers#readme",
51 + "keywords": [
52 + "event",
53 + "headers",
54 + "http",
55 + "onheaders"
56 + ],
57 + "license": "MIT",
58 + "name": "on-headers",
59 + "repository": {
60 + "type": "git",
61 + "url": "git+https://github.com/jshttp/on-headers.git"
62 + },
63 + "scripts": {
64 + "test": "mocha --reporter spec --bail --check-leaks test/",
65 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
66 + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
67 + },
68 + "version": "1.0.1"
69 +}
1 +2.4.5 / 2017-09-26
2 +==================
3 +
4 + * deps: etag@~1.8.1
5 + - perf: replace regular expression with substring
6 + * deps: fresh@0.5.2
7 + - Fix regression matching multiple ETags in `If-None-Match`
8 + - perf: improve `If-None-Match` token parsing
9 +
10 +2.4.4 / 2017-09-11
11 +==================
12 +
13 + * deps: fresh@0.5.1
14 + - Fix handling of modified headers with invalid dates
15 + - perf: improve ETag match loop
16 + * deps: parseurl@~1.3.2
17 + - perf: reduce overhead for full URLs
18 + - perf: unroll the "fast-path" `RegExp`
19 + * deps: safe-buffer@5.1.1
20 +
21 +2.4.3 / 2017-05-16
22 +==================
23 +
24 + * Use `safe-buffer` for improved Buffer API
25 + * deps: ms@2.0.0
26 +
27 +2.4.2 / 2017-03-24
28 +==================
29 +
30 + * deps: ms@1.0.0
31 +
32 +2.4.1 / 2017-02-27
33 +==================
34 +
35 + * Remove usage of `res._headers` private field
36 + * deps: fresh@0.5.0
37 + - Fix incorrect result when `If-None-Match` has both `*` and ETags
38 + - Fix weak `ETag` matching to match spec
39 + - perf: skip checking modified time if ETag check failed
40 + - perf: skip parsing `If-None-Match` when no `ETag` header
41 + - perf: use `Date.parse` instead of `new Date`
42 +
43 +2.4.0 / 2017-02-19
44 +==================
45 +
46 + * deps: etag@~1.8.0
47 + - Use SHA1 instead of MD5 for ETag hashing
48 + - Works with FIPS 140-2 OpenSSL configuration
49 + * deps: fresh@0.4.0
50 + - Fix false detection of `no-cache` request directive
51 + - perf: enable strict mode
52 + - perf: hoist regular expressions
53 + - perf: remove duplicate conditional
54 + - perf: remove unnecessary boolean coercions
55 + * perf: simplify initial argument checking
56 +
57 +2.3.2 / 2016-11-16
58 +==================
59 +
60 + * deps: ms@0.7.2
61 +
62 +2.3.1 / 2016-01-23
63 +==================
64 +
65 + * deps: parseurl@~1.3.1
66 + - perf: enable strict mode
67 +
68 +2.3.0 / 2015-06-13
69 +==================
70 +
71 + * Send non-chunked response for `OPTIONS`
72 + * deps: etag@~1.7.0
73 + - Always include entity length in ETags for hash length extensions
74 + - Generate non-Stats ETags using MD5 only (no longer CRC32)
75 + - Remove base64 padding in ETags to shorten
76 + * deps: fresh@0.3.0
77 + - Add weak `ETag` matching support
78 + * perf: enable strict mode
79 + * perf: remove argument reassignment
80 + * perf: remove bitwise operations
81 +
82 +2.2.1 / 2015-05-14
83 +==================
84 +
85 + * deps: etag@~1.6.0
86 + - Improve support for JXcore
87 + - Support "fake" stats objects in environments without `fs`
88 + * deps: ms@0.7.1
89 + - Prevent extraordinarily long inputs
90 +
91 +2.2.0 / 2014-12-18
92 +==================
93 +
94 + * Support query string in the URL
95 + * deps: etag@~1.5.1
96 + - deps: crc@3.2.1
97 + * deps: ms@0.7.0
98 + - Add `milliseconds`
99 + - Add `msecs`
100 + - Add `secs`
101 + - Add `mins`
102 + - Add `hrs`
103 + - Add `yrs`
104 +
105 +2.1.7 / 2014-11-19
106 +==================
107 +
108 + * Avoid errors from enumerables on `Object.prototype`
109 +
110 +2.1.6 / 2014-10-16
111 +==================
112 +
113 + * deps: etag@~1.5.0
114 +
115 +2.1.5 / 2014-09-24
116 +==================
117 +
118 + * deps: etag@~1.4.0
119 +
120 +2.1.4 / 2014-09-15
121 +==================
122 +
123 + * Fix content headers being sent in 304 response
124 + * deps: etag@~1.3.1
125 + - Improve ETag generation speed
126 +
127 +2.1.3 / 2014-09-07
128 +==================
129 +
130 + * deps: fresh@0.2.4
131 +
132 +2.1.2 / 2014-09-05
133 +==================
134 +
135 + * deps: etag@~1.3.0
136 + - Improve ETag generation speed
137 +
138 +2.1.1 / 2014-08-25
139 +==================
140 +
141 + * Fix `ms` to be listed as a dependency
142 +
143 +2.1.0 / 2014-08-24
144 +==================
145 +
146 + * Accept string for `maxAge` (converted by `ms`)
147 + * Use `etag` to generate `ETag` header
148 +
149 +2.0.1 / 2014-06-05
150 +==================
151 +
152 + * Reduce byte size of `ETag` header
153 +
154 +2.0.0 / 2014-05-02
155 +==================
156 +
157 + * `path` argument is required; there is no default icon.
158 + * Accept `Buffer` of icon as first argument.
159 + * Non-GET and HEAD requests are denied.
160 + * Send valid max-age value
161 + * Support conditional requests
162 + * Support max-age=0
163 + * Support OPTIONS method
164 + * Throw if `path` argument is directory.
165 +
166 +1.0.2 / 2014-03-16
167 +==================
168 +
169 + * Fixed content of default icon.
170 +
171 +1.0.1 / 2014-03-11
172 +==================
173 +
174 + * Fixed path to default icon.
175 +
176 +1.0.0 / 2014-02-15
177 +==================
178 +
179 + * Initial release
1 +(The MIT License)
2 +
3 +Copyright (c) 2010 Sencha Inc.
4 +Copyright (c) 2011 LearnBoost
5 +Copyright (c) 2011 TJ Holowaychuk
6 +Copyright (c) 2014-2017 Douglas Christopher Wilson
7 +
8 +Permission is hereby granted, free of charge, to any person obtaining
9 +a copy of this software and associated documentation files (the
10 +'Software'), to deal in the Software without restriction, including
11 +without limitation the rights to use, copy, modify, merge, publish,
12 +distribute, sublicense, and/or sell copies of the Software, and to
13 +permit persons to whom the Software is furnished to do so, subject to
14 +the following conditions:
15 +
16 +The above copyright notice and this permission notice shall be
17 +included in all copies or substantial portions of the Software.
18 +
19 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 +# serve-favicon
2 +
3 +[![NPM Version][npm-image]][npm-url]
4 +[![NPM Downloads][downloads-image]][downloads-url]
5 +[![Linux Build][travis-image]][travis-url]
6 +[![Windows Build][appveyor-image]][appveyor-url]
7 +[![Test Coverage][coveralls-image]][coveralls-url]
8 +[![Gratipay][gratipay-image]][gratipay-url]
9 +
10 +Node.js middleware for serving a favicon.
11 +
12 +A favicon is a visual cue that client software, like browsers, use to identify
13 +a site. For an example and more information, please visit
14 +[the Wikipedia article on favicons](https://en.wikipedia.org/wiki/Favicon).
15 +
16 +Why use this module?
17 +
18 + - User agents request `favicon.ico` frequently and indiscriminately, so you
19 + may wish to exclude these requests from your logs by using this middleware
20 + before your logger middleware.
21 + - This module caches the icon in memory to improve performance by skipping
22 + disk access.
23 + - This module provides an `ETag` based on the contents of the icon, rather
24 + than file system properties.
25 + - This module will serve with the most compatible `Content-Type`.
26 +
27 +**Note** This module is exclusively for serving the "default, implicit favicon",
28 +which is `GET /favicon.ico`. For additional vendor-specific icons that require
29 +HTML markup, additional middleware is required to serve the relevant files, for
30 +example [serve-static](https://npmjs.org/package/serve-static).
31 +
32 +## Install
33 +
34 +This is a [Node.js](https://nodejs.org/en/) module available through the
35 +[npm registry](https://www.npmjs.com/). Installation is done using the
36 +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
37 +
38 +```sh
39 +$ npm install serve-favicon
40 +```
41 +
42 +## API
43 +
44 +### favicon(path, options)
45 +
46 +Create new middleware to serve a favicon from the given `path` to a favicon file.
47 +`path` may also be a `Buffer` of the icon to serve.
48 +
49 +#### Options
50 +
51 +Serve favicon accepts these properties in the options object.
52 +
53 +##### maxAge
54 +
55 +The `cache-control` `max-age` directive in `ms`, defaulting to 1 year. This can
56 +also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
57 +module.
58 +
59 +## Examples
60 +
61 +Typically this middleware will come very early in your stack (maybe even first)
62 +to avoid processing any other middleware if we already know the request is for
63 +`/favicon.ico`.
64 +
65 +### express
66 +
67 +```javascript
68 +var express = require('express')
69 +var favicon = require('serve-favicon')
70 +var path = require('path')
71 +
72 +var app = express()
73 +app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
74 +
75 +// Add your routes here, etc.
76 +
77 +app.listen(3000)
78 +```
79 +
80 +### connect
81 +
82 +```javascript
83 +var connect = require('connect')
84 +var favicon = require('serve-favicon')
85 +var path = require('path')
86 +
87 +var app = connect()
88 +app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
89 +
90 +// Add your middleware here, etc.
91 +
92 +app.listen(3000)
93 +```
94 +
95 +### vanilla http server
96 +
97 +This middleware can be used anywhere, even outside express/connect. It takes
98 +`req`, `res`, and `callback`.
99 +
100 +```javascript
101 +var http = require('http')
102 +var favicon = require('serve-favicon')
103 +var finalhandler = require('finalhandler')
104 +var path = require('path')
105 +
106 +var _favicon = favicon(path.join(__dirname, 'public', 'favicon.ico'))
107 +
108 +var server = http.createServer(function onRequest (req, res) {
109 + var done = finalhandler(req, res)
110 +
111 + _favicon(req, res, function onNext (err) {
112 + if (err) return done(err)
113 +
114 + // continue to process the request here, etc.
115 +
116 + res.statusCode = 404
117 + res.end('oops')
118 + })
119 +})
120 +
121 +server.listen(3000)
122 +```
123 +
124 +## License
125 +
126 +[MIT](LICENSE)
127 +
128 +[npm-image]: https://img.shields.io/npm/v/serve-favicon.svg
129 +[npm-url]: https://npmjs.org/package/serve-favicon
130 +[travis-image]: https://img.shields.io/travis/expressjs/serve-favicon/master.svg?label=linux
131 +[travis-url]: https://travis-ci.org/expressjs/serve-favicon
132 +[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/serve-favicon/master.svg?label=windows
133 +[appveyor-url]: https://ci.appveyor.com/project/dougwilson/serve-favicon
134 +[coveralls-image]: https://img.shields.io/coveralls/expressjs/serve-favicon.svg
135 +[coveralls-url]: https://coveralls.io/r/expressjs/serve-favicon?branch=master
136 +[downloads-image]: https://img.shields.io/npm/dm/serve-favicon.svg
137 +[downloads-url]: https://npmjs.org/package/serve-favicon
138 +[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
139 +[gratipay-url]: https://www.gratipay.com/dougwilson/
1 +/*!
2 + * serve-favicon
3 + * Copyright(c) 2010 Sencha Inc.
4 + * Copyright(c) 2011 TJ Holowaychuk
5 + * Copyright(c) 2014-2017 Douglas Christopher Wilson
6 + * MIT Licensed
7 + */
8 +
9 +'use strict'
10 +
11 +/**
12 + * Module dependencies.
13 + * @private
14 + */
15 +
16 +var Buffer = require('safe-buffer').Buffer
17 +var etag = require('etag')
18 +var fresh = require('fresh')
19 +var fs = require('fs')
20 +var ms = require('ms')
21 +var parseUrl = require('parseurl')
22 +var path = require('path')
23 +var resolve = path.resolve
24 +
25 +/**
26 + * Module exports.
27 + * @public
28 + */
29 +
30 +module.exports = favicon
31 +
32 +/**
33 + * Module variables.
34 + * @private
35 + */
36 +
37 +var ONE_YEAR_MS = 60 * 60 * 24 * 365 * 1000 // 1 year
38 +
39 +/**
40 + * Serves the favicon located by the given `path`.
41 + *
42 + * @public
43 + * @param {String|Buffer} path
44 + * @param {Object} [options]
45 + * @return {Function} middleware
46 + */
47 +
48 +function favicon (path, options) {
49 + var opts = options || {}
50 +
51 + var icon // favicon cache
52 + var maxAge = calcMaxAge(opts.maxAge)
53 +
54 + if (!path) {
55 + throw new TypeError('path to favicon.ico is required')
56 + }
57 +
58 + if (Buffer.isBuffer(path)) {
59 + icon = createIcon(Buffer.from(path), maxAge)
60 + } else if (typeof path === 'string') {
61 + path = resolveSync(path)
62 + } else {
63 + throw new TypeError('path to favicon.ico must be string or buffer')
64 + }
65 +
66 + return function favicon (req, res, next) {
67 + if (parseUrl(req).pathname !== '/favicon.ico') {
68 + next()
69 + return
70 + }
71 +
72 + if (req.method !== 'GET' && req.method !== 'HEAD') {
73 + res.statusCode = req.method === 'OPTIONS' ? 200 : 405
74 + res.setHeader('Allow', 'GET, HEAD, OPTIONS')
75 + res.setHeader('Content-Length', '0')
76 + res.end()
77 + return
78 + }
79 +
80 + if (icon) {
81 + send(req, res, icon)
82 + return
83 + }
84 +
85 + fs.readFile(path, function (err, buf) {
86 + if (err) return next(err)
87 + icon = createIcon(buf, maxAge)
88 + send(req, res, icon)
89 + })
90 + }
91 +}
92 +
93 +/**
94 + * Calculate the max-age from a configured value.
95 + *
96 + * @private
97 + * @param {string|number} val
98 + * @return {number}
99 + */
100 +
101 +function calcMaxAge (val) {
102 + var num = typeof val === 'string'
103 + ? ms(val)
104 + : val
105 +
106 + return num != null
107 + ? Math.min(Math.max(0, num), ONE_YEAR_MS)
108 + : ONE_YEAR_MS
109 +}
110 +
111 +/**
112 + * Create icon data from Buffer and max-age.
113 + *
114 + * @private
115 + * @param {Buffer} buf
116 + * @param {number} maxAge
117 + * @return {object}
118 + */
119 +
120 +function createIcon (buf, maxAge) {
121 + return {
122 + body: buf,
123 + headers: {
124 + 'Cache-Control': 'public, max-age=' + Math.floor(maxAge / 1000),
125 + 'ETag': etag(buf)
126 + }
127 + }
128 +}
129 +
130 +/**
131 + * Create EISDIR error.
132 + *
133 + * @private
134 + * @param {string} path
135 + * @return {Error}
136 + */
137 +
138 +function createIsDirError (path) {
139 + var error = new Error('EISDIR, illegal operation on directory \'' + path + '\'')
140 + error.code = 'EISDIR'
141 + error.errno = 28
142 + error.path = path
143 + error.syscall = 'open'
144 + return error
145 +}
146 +
147 +/**
148 + * Determine if the cached representation is fresh.
149 + *
150 + * @param {object} req
151 + * @param {object} res
152 + * @return {boolean}
153 + * @private
154 + */
155 +
156 +function isFresh (req, res) {
157 + return fresh(req.headers, {
158 + 'etag': res.getHeader('ETag'),
159 + 'last-modified': res.getHeader('Last-Modified')
160 + })
161 +}
162 +
163 +/**
164 + * Resolve the path to icon.
165 + *
166 + * @param {string} iconPath
167 + * @private
168 + */
169 +
170 +function resolveSync (iconPath) {
171 + var path = resolve(iconPath)
172 + var stat = fs.statSync(path)
173 +
174 + if (stat.isDirectory()) {
175 + throw createIsDirError(path)
176 + }
177 +
178 + return path
179 +}
180 +
181 +/**
182 + * Send icon data in response to a request.
183 + *
184 + * @private
185 + * @param {IncomingMessage} req
186 + * @param {OutgoingMessage} res
187 + * @param {object} icon
188 + */
189 +
190 +function send (req, res, icon) {
191 + // Set headers
192 + var headers = icon.headers
193 + var keys = Object.keys(headers)
194 + for (var i = 0; i < keys.length; i++) {
195 + var key = keys[i]
196 + res.setHeader(key, headers[key])
197 + }
198 +
199 + // Validate freshness
200 + if (isFresh(req, res)) {
201 + res.statusCode = 304
202 + res.end()
203 + return
204 + }
205 +
206 + // Send icon
207 + res.statusCode = 200
208 + res.setHeader('Content-Length', icon.body.length)
209 + res.setHeader('Content-Type', 'image/x-icon')
210 + res.end(icon.body)
211 +}
1 +{
2 + "_from": "serve-favicon@~2.4.5",
3 + "_id": "serve-favicon@2.4.5",
4 + "_inBundle": false,
5 + "_integrity": "sha512-s7F8h2NrslMkG50KxvlGdj+ApSwaLex0vexuJ9iFf3GLTIp1ph/l1qZvRe9T9TJEYZgmq72ZwJ2VYiAEtChknw==",
6 + "_location": "/serve-favicon",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "serve-favicon@~2.4.5",
12 + "name": "serve-favicon",
13 + "escapedName": "serve-favicon",
14 + "rawSpec": "~2.4.5",
15 + "saveSpec": null,
16 + "fetchSpec": "~2.4.5"
17 + },
18 + "_requiredBy": [
19 + "/"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.5.tgz",
22 + "_shasum": "49d9a46863153a9240691c893d2b0e7d85d6d436",
23 + "_spec": "serve-favicon@~2.4.5",
24 + "_where": "/home/ubuntu/OpenSource_Project",
25 + "author": {
26 + "name": "Douglas Christopher Wilson",
27 + "email": "doug@somethingdoug.com"
28 + },
29 + "bugs": {
30 + "url": "https://github.com/expressjs/serve-favicon/issues"
31 + },
32 + "bundleDependencies": false,
33 + "dependencies": {
34 + "etag": "~1.8.1",
35 + "fresh": "0.5.2",
36 + "ms": "2.0.0",
37 + "parseurl": "~1.3.2",
38 + "safe-buffer": "5.1.1"
39 + },
40 + "deprecated": false,
41 + "description": "favicon serving middleware with caching",
42 + "devDependencies": {
43 + "eslint": "3.19.0",
44 + "eslint-config-standard": "10.2.1",
45 + "eslint-plugin-import": "2.7.0",
46 + "eslint-plugin-markdown": "1.0.0-beta.6",
47 + "eslint-plugin-node": "5.1.1",
48 + "eslint-plugin-promise": "3.5.0",
49 + "eslint-plugin-standard": "3.0.1",
50 + "istanbul": "0.4.5",
51 + "mocha": "2.5.3",
52 + "supertest": "1.1.0",
53 + "temp-path": "1.0.0"
54 + },
55 + "engines": {
56 + "node": ">= 0.8.0"
57 + },
58 + "files": [
59 + "LICENSE",
60 + "HISTORY.md",
61 + "index.js"
62 + ],
63 + "homepage": "https://github.com/expressjs/serve-favicon#readme",
64 + "keywords": [
65 + "express",
66 + "favicon",
67 + "middleware"
68 + ],
69 + "license": "MIT",
70 + "name": "serve-favicon",
71 + "repository": {
72 + "type": "git",
73 + "url": "git+https://github.com/expressjs/serve-favicon.git"
74 + },
75 + "scripts": {
76 + "lint": "eslint --plugin markdown --ext js,md .",
77 + "test": "mocha --reporter spec --bail --check-leaks test/",
78 + "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
79 + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
80 + },
81 + "version": "2.4.5"
82 +}
1 { 1 {
2 - "requires": true, 2 + "name": "project",
3 + "version": "0.0.0",
3 "lockfileVersion": 1, 4 "lockfileVersion": 1,
5 + "requires": true,
4 "dependencies": { 6 "dependencies": {
5 "accepts": { 7 "accepts": {
6 "version": "1.3.4", 8 "version": "1.3.4",
...@@ -52,6 +54,14 @@ ...@@ -52,6 +54,14 @@
52 "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 54 "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
53 "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" 55 "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
54 }, 56 },
57 + "basic-auth": {
58 + "version": "2.0.0",
59 + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
60 + "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
61 + "requires": {
62 + "safe-buffer": "5.1.1"
63 + }
64 + },
55 "bcrypt-pbkdf": { 65 "bcrypt-pbkdf": {
56 "version": "1.0.1", 66 "version": "1.0.1",
57 "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 67 "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
...@@ -124,6 +134,15 @@ ...@@ -124,6 +134,15 @@
124 "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 134 "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
125 "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 135 "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
126 }, 136 },
137 + "cookie-parser": {
138 + "version": "1.4.3",
139 + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
140 + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
141 + "requires": {
142 + "cookie": "0.3.1",
143 + "cookie-signature": "1.0.6"
144 + }
145 + },
127 "cookie-signature": { 146 "cookie-signature": {
128 "version": "1.0.6", 147 "version": "1.0.6",
129 "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 148 "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
...@@ -197,6 +216,11 @@ ...@@ -197,6 +216,11 @@
197 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 216 "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
198 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 217 "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
199 }, 218 },
219 + "ejs": {
220 + "version": "2.5.7",
221 + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
222 + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo="
223 + },
200 "encodeurl": { 224 "encodeurl": {
201 "version": "1.0.1", 225 "version": "1.0.1",
202 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 226 "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
...@@ -464,6 +488,18 @@ ...@@ -464,6 +488,18 @@
464 "mime-db": "1.30.0" 488 "mime-db": "1.30.0"
465 } 489 }
466 }, 490 },
491 + "morgan": {
492 + "version": "1.9.0",
493 + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
494 + "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
495 + "requires": {
496 + "basic-auth": "2.0.0",
497 + "debug": "2.6.9",
498 + "depd": "1.1.1",
499 + "on-finished": "2.3.0",
500 + "on-headers": "1.0.1"
501 + }
502 + },
467 "ms": { 503 "ms": {
468 "version": "2.0.0", 504 "version": "2.0.0",
469 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 505 "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
...@@ -487,6 +523,11 @@ ...@@ -487,6 +523,11 @@
487 "ee-first": "1.1.1" 523 "ee-first": "1.1.1"
488 } 524 }
489 }, 525 },
526 + "on-headers": {
527 + "version": "1.0.1",
528 + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
529 + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
530 + },
490 "parseurl": { 531 "parseurl": {
491 "version": "1.3.2", 532 "version": "1.3.2",
492 "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 533 "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
...@@ -591,6 +632,18 @@ ...@@ -591,6 +632,18 @@
591 "statuses": "1.3.1" 632 "statuses": "1.3.1"
592 } 633 }
593 }, 634 },
635 + "serve-favicon": {
636 + "version": "2.4.5",
637 + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.4.5.tgz",
638 + "integrity": "sha512-s7F8h2NrslMkG50KxvlGdj+ApSwaLex0vexuJ9iFf3GLTIp1ph/l1qZvRe9T9TJEYZgmq72ZwJ2VYiAEtChknw==",
639 + "requires": {
640 + "etag": "1.8.1",
641 + "fresh": "0.5.2",
642 + "ms": "2.0.0",
643 + "parseurl": "1.3.2",
644 + "safe-buffer": "5.1.1"
645 + }
646 + },
594 "serve-static": { 647 "serve-static": {
595 "version": "1.13.1", 648 "version": "1.13.1",
596 "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", 649 "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
......
1 +{
2 + "name": "project",
3 + "version": "0.0.0",
4 + "private": true,
5 + "scripts": {
6 + "start": "node ./bin/www"
7 + },
8 + "dependencies": {
9 + "body-parser": "~1.18.2",
10 + "cookie-parser": "~1.4.3",
11 + "debug": "~2.6.9",
12 + "ejs": "~2.5.7",
13 + "express": "^4.16.2",
14 + "morgan": "~1.9.0",
15 + "request": "^2.83.0",
16 + "serve-favicon": "~2.4.5"
17 + },
18 + "main": "app.js",
19 + "devDependencies": {},
20 + "author": "",
21 + "license": "ISC",
22 + "description": ""
23 +}
1 +var express = require('express');
2 +var app = express.Router();
3 +
4 +// Kakao Keyboard API
5 +app.get('/', function(req, res) {
6 + const menu = {
7 + "type": 'buttons',
8 + "buttons": ["/설정", "/시작"]};
9 +
10 + res.status(200).set({
11 + 'content-type': 'application/json'
12 + }).send(JSON.stringify(menu));
13 +});
14 +
15 +
16 +module.exports = app;
17 +
1 +var express = require('express');
2 +var request = require('request');
3 +var app = express.Router();
4 +
5 +// Naver Auth Key
6 +var client_id = '86rKmat0DijccSxKa01P';
7 +var client_secret = 'rMapNjB8DP';
8 +
9 +// Naver API URL
10 +var api_url = 'https://openapi.naver.com/v1/papago/n2mt';
11 +
12 +// Kakao Message API
13 +app.post('/', function(req, res) {
14 + const _obj = {
15 + user_key: req.body.user_key,
16 + type: req.body.type,
17 + content: req.body.content
18 + };
19 +
20 + console.log(_obj.content)
21 +
22 + if(_obj.content == '/시작'){
23 + res.set('content-type', 'application/json');
24 + res.json({
25 + "message": {
26 + "text": "언어를 설정하고 싶으면 /설정 이라고 타이핑 해주세요"
27 + },
28 + "keyboard": {
29 + "type": "text"
30 + }
31 + });
32 + }
33 +else{
34 + // Naver Papago Translate
35 + var options = {
36 + url: api_url,
37 + // 한국어(source : ko), 영어(target: en), 카톡에서 받는 메시지(text)
38 + form: {'source':'ko', 'target':'en', 'text':req.body.content},
39 + headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret}
40 + };
41 +console.log('aa');
42 + // Naver Post API
43 + request.post(options, function(error, response, body){
44 + // Translate API Sucess
45 + if(!error && response.statusCode == 200){
46 + // JSON
47 + var objBody = JSON.parse(response.body);
48 + // Message 잘 찍히는지 확인
49 + console.log(objBody.message.result.translatedText);
50 +
51 + // Kakao Message API
52 + let massage = {
53 + "message": {
54 + // Naver API Translate 결과를 Kakao Message
55 + "text": objBody.message.result.translatedText
56 + },
57 + };
58 +
59 + // Kakao Message API 전송
60 + res.set({
61 + 'content-type': 'application/json'
62 + }).send(JSON.stringify(massage));
63 + }else{
64 + // Naver Message Error 발생
65 + res.status(response.statusCode).end();
66 + console.log('error = ' + response.statusCode);
67 +
68 + let massage = {
69 + "message": {
70 + "text": response.statusCode
71 + },
72 + };
73 +
74 + // Kakao에 Error Message
75 + res.set({
76 + 'content-type': 'application/json'
77 + }).send(JSON.stringify(massage));
78 + }
79 + });
80 +}
81 +});
82 +
83 +module.exports = app;
84 +