Showing
741 changed files
with
4005 additions
and
2 deletions
... | @@ -3,10 +3,22 @@ var express = require('express'); | ... | @@ -3,10 +3,22 @@ var express = require('express'); |
3 | var path = require('path'); | 3 | var path = require('path'); |
4 | var cookieParser = require('cookie-parser'); | 4 | var cookieParser = require('cookie-parser'); |
5 | var logger = require('morgan'); | 5 | var logger = require('morgan'); |
6 | - | 6 | +var passport = require('passport'); |
7 | +var session = require('express-session'); | ||
7 | var index = require('./routes/index'); | 8 | var index = require('./routes/index'); |
8 | var users = require('./routes/users'); | 9 | var users = require('./routes/users'); |
9 | var calendar = require('./routes/calendar'); | 10 | var calendar = require('./routes/calendar'); |
11 | +var login = require('./routes/login'); | ||
12 | + | ||
13 | +passport.serializeUser(function(user,done) { | ||
14 | + console.log('serialized'); | ||
15 | + done(null,user); | ||
16 | +}); | ||
17 | +passport.deserializeUser(function(user,done){ | ||
18 | + console.log('deserialized'); | ||
19 | + done(null,user); | ||
20 | +}) | ||
21 | + | ||
10 | var app = express(); | 22 | var app = express(); |
11 | 23 | ||
12 | // view engine setup (뷰 폴더 경로 설정) | 24 | // view engine setup (뷰 폴더 경로 설정) |
... | @@ -19,9 +31,19 @@ app.use(express.urlencoded({ extended: false })); | ... | @@ -19,9 +31,19 @@ app.use(express.urlencoded({ extended: false })); |
19 | app.use(cookieParser()); | 31 | app.use(cookieParser()); |
20 | app.use(express.static(path.join(__dirname, 'public'))); | 32 | app.use(express.static(path.join(__dirname, 'public'))); |
21 | 33 | ||
34 | +app.use(session({ | ||
35 | + secret: 'secrettexthere', | ||
36 | + saveUninitialized: true, | ||
37 | + resave: true | ||
38 | +})); | ||
39 | + | ||
40 | + | ||
41 | +app.use(passport.initialize()); | ||
42 | +app.use(passport.session()); | ||
22 | app.use('/', index); | 43 | app.use('/', index); |
23 | app.use('/users', users); | 44 | app.use('/users', users); |
24 | app.use('/calendar',calendar); | 45 | app.use('/calendar',calendar); |
46 | +app.use('/login',login); | ||
25 | 47 | ||
26 | // catch 404 and forward to error handler | 48 | // catch 404 and forward to error handler |
27 | app.use(function(req, res, next) { | 49 | app.use(function(req, res, next) { | ... | ... |
1 | -{"web":{"client_id":"978869138601-u3euf0c04sbdor68r30m599gilvjn91e.apps.googleusercontent.com","project_id":"reminder-talk","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"N7Uh_oVQZt-almzA4DkM4bm_","redirect_uris":["http://localhost:3000"],"javascript_origins":["http://localhost:3000"]}} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +{"web":{"client_id":"978869138601-u3euf0c04sbdor68r30m599gilvjn91e.apps.googleusercontent.com","project_id":"reminder-talk","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"N7Uh_oVQZt-almzA4DkM4bm_","redirect_uris":["http://localhost:3000","http://localhost:3000/auth/success","http://localhost:3000/auth","http://localhost/auth/callback"],"javascript_origins":["http://localhost:3000"]}} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
node_modules/.bin/needle
0 → 100644
1 | +#!/bin/sh | ||
2 | +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") | ||
3 | + | ||
4 | +case `uname` in | ||
5 | + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; | ||
6 | +esac | ||
7 | + | ||
8 | +if [ -x "$basedir/node" ]; then | ||
9 | + "$basedir/node" "$basedir/../needle/bin/needle" "$@" | ||
10 | + ret=$? | ||
11 | +else | ||
12 | + node "$basedir/../needle/bin/needle" "$@" | ||
13 | + ret=$? | ||
14 | +fi | ||
15 | +exit $ret |
node_modules/.bin/needle.cmd
0 → 100644
1 | +@ECHO off | ||
2 | +SETLOCAL | ||
3 | +CALL :find_dp0 | ||
4 | + | ||
5 | +IF EXIST "%dp0%\node.exe" ( | ||
6 | + SET "_prog=%dp0%\node.exe" | ||
7 | +) ELSE ( | ||
8 | + SET "_prog=node" | ||
9 | + SET PATHEXT=%PATHEXT:;.JS;=;% | ||
10 | +) | ||
11 | + | ||
12 | +"%_prog%" "%dp0%\..\needle\bin\needle" %* | ||
13 | +ENDLOCAL | ||
14 | +EXIT /b %errorlevel% | ||
15 | +:find_dp0 | ||
16 | +SET dp0=%~dp0 | ||
17 | +EXIT /b |
node_modules/.bin/needle.ps1
0 → 100644
1 | +#!/usr/bin/env pwsh | ||
2 | +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent | ||
3 | + | ||
4 | +$exe="" | ||
5 | +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { | ||
6 | + # Fix case when both the Windows and Linux builds of Node | ||
7 | + # are installed in the same directory | ||
8 | + $exe=".exe" | ||
9 | +} | ||
10 | +$ret=0 | ||
11 | +if (Test-Path "$basedir/node$exe") { | ||
12 | + & "$basedir/node$exe" "$basedir/../needle/bin/needle" $args | ||
13 | + $ret=$LASTEXITCODE | ||
14 | +} else { | ||
15 | + & "node$exe" "$basedir/../needle/bin/needle" $args | ||
16 | + $ret=$LASTEXITCODE | ||
17 | +} | ||
18 | +exit $ret |
node_modules/buffer-crc32/.npmignore
0 → 100644
1 | +node_modules | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/buffer-crc32/.travis.yml
0 → 100644
node_modules/buffer-crc32/README.md
0 → 100644
1 | +# buffer-crc32 | ||
2 | + | ||
3 | +[](http://travis-ci.org/brianloveswords/buffer-crc32) | ||
4 | + | ||
5 | +crc32 that works with binary data and fancy character sets, outputs | ||
6 | +buffer, signed or unsigned data and has tests. | ||
7 | + | ||
8 | +Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix | ||
9 | + | ||
10 | +# install | ||
11 | +``` | ||
12 | +npm install buffer-crc32 | ||
13 | +``` | ||
14 | + | ||
15 | +# example | ||
16 | +```js | ||
17 | +var crc32 = require('buffer-crc32'); | ||
18 | +// works with buffers | ||
19 | +var buf = Buffer([0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00]) | ||
20 | +crc32(buf) // -> <Buffer 94 5a ab 4a> | ||
21 | + | ||
22 | +// has convenience methods for getting signed or unsigned ints | ||
23 | +crc32.signed(buf) // -> -1805997238 | ||
24 | +crc32.unsigned(buf) // -> 2488970058 | ||
25 | + | ||
26 | +// will cast to buffer if given a string, so you can | ||
27 | +// directly use foreign characters safely | ||
28 | +crc32('自動販売機') // -> <Buffer cb 03 1a c5> | ||
29 | + | ||
30 | +// and works in append mode too | ||
31 | +var partialCrc = crc32('hey'); | ||
32 | +var partialCrc = crc32(' ', partialCrc); | ||
33 | +var partialCrc = crc32('sup', partialCrc); | ||
34 | +var partialCrc = crc32(' ', partialCrc); | ||
35 | +var finalCrc = crc32('bros', partialCrc); // -> <Buffer 47 fa 55 70> | ||
36 | +``` | ||
37 | + | ||
38 | +# tests | ||
39 | +This was tested against the output of zlib's crc32 method. You can run | ||
40 | +the tests with`npm test` (requires tap) | ||
41 | + | ||
42 | +# see also | ||
43 | +https://github.com/alexgorbatchev/node-crc, `crc.buffer.crc32` also | ||
44 | +supports buffer inputs and return unsigned ints (thanks @tjholowaychuk). | ||
45 | + | ||
46 | +# license | ||
47 | +MIT/X11 |
node_modules/buffer-crc32/index.js
0 → 100644
1 | +var Buffer = require('buffer').Buffer; | ||
2 | + | ||
3 | +var CRC_TABLE = [ | ||
4 | + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, | ||
5 | + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, | ||
6 | + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, | ||
7 | + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, | ||
8 | + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, | ||
9 | + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | ||
10 | + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, | ||
11 | + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, | ||
12 | + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, | ||
13 | + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, | ||
14 | + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, | ||
15 | + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | ||
16 | + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, | ||
17 | + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, | ||
18 | + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, | ||
19 | + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, | ||
20 | + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, | ||
21 | + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | ||
22 | + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, | ||
23 | + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, | ||
24 | + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, | ||
25 | + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, | ||
26 | + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, | ||
27 | + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | ||
28 | + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, | ||
29 | + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, | ||
30 | + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, | ||
31 | + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, | ||
32 | + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, | ||
33 | + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | ||
34 | + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, | ||
35 | + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, | ||
36 | + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, | ||
37 | + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, | ||
38 | + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, | ||
39 | + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | ||
40 | + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, | ||
41 | + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, | ||
42 | + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, | ||
43 | + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, | ||
44 | + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, | ||
45 | + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | ||
46 | + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, | ||
47 | + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, | ||
48 | + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, | ||
49 | + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, | ||
50 | + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, | ||
51 | + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | ||
52 | + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, | ||
53 | + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, | ||
54 | + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, | ||
55 | + 0x2d02ef8d | ||
56 | +]; | ||
57 | + | ||
58 | +function bufferizeInt(num) { | ||
59 | + var tmp = Buffer(4); | ||
60 | + tmp.writeInt32BE(num, 0); | ||
61 | + return tmp; | ||
62 | +} | ||
63 | + | ||
64 | +function _crc32(buf, previous) { | ||
65 | + if (!Buffer.isBuffer(buf)) { | ||
66 | + buf = Buffer(buf); | ||
67 | + } | ||
68 | + if (Buffer.isBuffer(previous)) { | ||
69 | + previous = previous.readUInt32BE(0); | ||
70 | + } | ||
71 | + var crc = ~~previous ^ -1; | ||
72 | + for (var n = 0; n < buf.length; n++) { | ||
73 | + crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8); | ||
74 | + } | ||
75 | + return (crc ^ -1); | ||
76 | +} | ||
77 | + | ||
78 | +function crc32() { | ||
79 | + return bufferizeInt(_crc32.apply(null, arguments)); | ||
80 | +} | ||
81 | +crc32.signed = function () { | ||
82 | + return _crc32.apply(null, arguments); | ||
83 | +}; | ||
84 | +crc32.unsigned = function () { | ||
85 | + return _crc32.apply(null, arguments) >>> 0; | ||
86 | +}; | ||
87 | + | ||
88 | +module.exports = crc32; |
node_modules/buffer-crc32/package.json
0 → 100644
1 | +{ | ||
2 | + "_from": "buffer-crc32@0.2.1", | ||
3 | + "_id": "buffer-crc32@0.2.1", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=", | ||
6 | + "_location": "/buffer-crc32", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "version", | ||
10 | + "registry": true, | ||
11 | + "raw": "buffer-crc32@0.2.1", | ||
12 | + "name": "buffer-crc32", | ||
13 | + "escapedName": "buffer-crc32", | ||
14 | + "rawSpec": "0.2.1", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "0.2.1" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/connect", | ||
20 | + "/google-calendar/express" | ||
21 | + ], | ||
22 | + "_resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", | ||
23 | + "_shasum": "be3e5382fc02b6d6324956ac1af98aa98b08534c", | ||
24 | + "_spec": "buffer-crc32@0.2.1", | ||
25 | + "_where": "C:\\Users\\LG\\Desktop\\4-1\\Reminder-Talk\\node_modules\\google-calendar\\node_modules\\express", | ||
26 | + "author": { | ||
27 | + "name": "Brian J. Brennan", | ||
28 | + "email": "brianloveswords@gmail.com", | ||
29 | + "url": "http://bjb.io" | ||
30 | + }, | ||
31 | + "bugs": { | ||
32 | + "url": "https://github.com/brianloveswords/buffer-crc32/issues" | ||
33 | + }, | ||
34 | + "bundleDependencies": false, | ||
35 | + "contributors": [ | ||
36 | + { | ||
37 | + "name": "Vladimir Kuznetsov" | ||
38 | + } | ||
39 | + ], | ||
40 | + "dependencies": {}, | ||
41 | + "deprecated": false, | ||
42 | + "description": "A pure javascript CRC32 algorithm that plays nice with binary data", | ||
43 | + "devDependencies": { | ||
44 | + "tap": "~0.2.5" | ||
45 | + }, | ||
46 | + "engines": { | ||
47 | + "node": "*" | ||
48 | + }, | ||
49 | + "homepage": "https://github.com/brianloveswords/buffer-crc32", | ||
50 | + "main": "index.js", | ||
51 | + "name": "buffer-crc32", | ||
52 | + "optionalDependencies": {}, | ||
53 | + "repository": { | ||
54 | + "type": "git", | ||
55 | + "url": "git://github.com/brianloveswords/buffer-crc32.git" | ||
56 | + }, | ||
57 | + "scripts": { | ||
58 | + "test": "tap tests/*.test.js" | ||
59 | + }, | ||
60 | + "version": "0.2.1" | ||
61 | +} |
node_modules/buffer-crc32/tests/crc.test.js
0 → 100644
1 | +var crc32 = require('..'); | ||
2 | +var test = require('tap').test; | ||
3 | + | ||
4 | +test('simple crc32 is no problem', function (t) { | ||
5 | + var input = Buffer('hey sup bros'); | ||
6 | + var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); | ||
7 | + t.same(crc32(input), expected); | ||
8 | + t.end(); | ||
9 | +}); | ||
10 | + | ||
11 | +test('another simple one', function (t) { | ||
12 | + var input = Buffer('IEND'); | ||
13 | + var expected = Buffer([0xae, 0x42, 0x60, 0x82]); | ||
14 | + t.same(crc32(input), expected); | ||
15 | + t.end(); | ||
16 | +}); | ||
17 | + | ||
18 | +test('slightly more complex', function (t) { | ||
19 | + var input = Buffer([0x00, 0x00, 0x00]); | ||
20 | + var expected = Buffer([0xff, 0x41, 0xd9, 0x12]); | ||
21 | + t.same(crc32(input), expected); | ||
22 | + t.end(); | ||
23 | +}); | ||
24 | + | ||
25 | +test('complex crc32 gets calculated like a champ', function (t) { | ||
26 | + var input = Buffer('शीर्षक'); | ||
27 | + var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); | ||
28 | + t.same(crc32(input), expected); | ||
29 | + t.end(); | ||
30 | +}); | ||
31 | + | ||
32 | +test('casts to buffer if necessary', function (t) { | ||
33 | + var input = 'शीर्षक'; | ||
34 | + var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]); | ||
35 | + t.same(crc32(input), expected); | ||
36 | + t.end(); | ||
37 | +}); | ||
38 | + | ||
39 | +test('can do signed', function (t) { | ||
40 | + var input = 'ham sandwich'; | ||
41 | + var expected = -1891873021; | ||
42 | + t.same(crc32.signed(input), expected); | ||
43 | + t.end(); | ||
44 | +}); | ||
45 | + | ||
46 | +test('can do unsigned', function (t) { | ||
47 | + var input = 'bear sandwich'; | ||
48 | + var expected = 3711466352; | ||
49 | + t.same(crc32.unsigned(input), expected); | ||
50 | + t.end(); | ||
51 | +}); | ||
52 | + | ||
53 | + | ||
54 | +test('simple crc32 in append mode', function (t) { | ||
55 | + var input = [Buffer('hey'), Buffer(' '), Buffer('sup'), Buffer(' '), Buffer('bros')]; | ||
56 | + var expected = Buffer([0x47, 0xfa, 0x55, 0x70]); | ||
57 | + for (var crc = 0, i = 0; i < input.length; i++) { | ||
58 | + crc = crc32(input[i], crc); | ||
59 | + } | ||
60 | + t.same(crc, expected); | ||
61 | + t.end(); | ||
62 | +}); | ||
63 | + | ||
64 | + | ||
65 | +test('can do signed in append mode', function (t) { | ||
66 | + var input1 = 'ham'; | ||
67 | + var input2 = ' '; | ||
68 | + var input3 = 'sandwich'; | ||
69 | + var expected = -1891873021; | ||
70 | + | ||
71 | + var crc = crc32.signed(input1); | ||
72 | + crc = crc32.signed(input2, crc); | ||
73 | + crc = crc32.signed(input3, crc); | ||
74 | + | ||
75 | + t.same(crc, expected); | ||
76 | + t.end(); | ||
77 | +}); | ||
78 | + | ||
79 | +test('can do unsigned in append mode', function (t) { | ||
80 | + var input1 = 'bear san'; | ||
81 | + var input2 = 'dwich'; | ||
82 | + var expected = 3711466352; | ||
83 | + | ||
84 | + var crc = crc32.unsigned(input1); | ||
85 | + crc = crc32.unsigned(input2, crc); | ||
86 | + t.same(crc, expected); | ||
87 | + t.end(); | ||
88 | +}); | ||
89 | + |
node_modules/connect/.npmignore
0 → 100644
node_modules/connect/.travis.yml
0 → 100644
node_modules/connect/LICENSE
0 → 100644
1 | +(The MIT License) | ||
2 | + | ||
3 | +Copyright (c) 2010 Sencha Inc. | ||
4 | +Copyright (c) 2011 LearnBoost | ||
5 | +Copyright (c) 2011 TJ Holowaychuk | ||
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. | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/connect/Readme.md
0 → 100644
1 | +[](http://travis-ci.org/senchalabs/connect) | ||
2 | +# Connect | ||
3 | + | ||
4 | + Connect is an extensible HTTP server framework for [node](http://nodejs.org), providing high performance "plugins" known as _middleware_. | ||
5 | + | ||
6 | + Connect is bundled with over _20_ commonly used middleware, including | ||
7 | + a logger, session support, cookie parser, and [more](http://senchalabs.github.com/connect). Be sure to view the 2.x [documentation](http://senchalabs.github.com/connect/). | ||
8 | + | ||
9 | +```js | ||
10 | +var connect = require('connect') | ||
11 | + , http = require('http'); | ||
12 | + | ||
13 | +var app = connect() | ||
14 | + .use(connect.favicon()) | ||
15 | + .use(connect.logger('dev')) | ||
16 | + .use(connect.static('public')) | ||
17 | + .use(connect.directory('public')) | ||
18 | + .use(connect.cookieParser()) | ||
19 | + .use(connect.session({ secret: 'my secret here' })) | ||
20 | + .use(function(req, res){ | ||
21 | + res.end('Hello from Connect!\n'); | ||
22 | + }); | ||
23 | + | ||
24 | +http.createServer(app).listen(3000); | ||
25 | +``` | ||
26 | + | ||
27 | +## Middleware | ||
28 | + | ||
29 | + - [csrf](http://www.senchalabs.org/connect/csrf.html) | ||
30 | + - [basicAuth](http://www.senchalabs.org/connect/basicAuth.html) | ||
31 | + - [bodyParser](http://www.senchalabs.org/connect/bodyParser.html) | ||
32 | + - [json](http://www.senchalabs.org/connect/json.html) | ||
33 | + - [multipart](http://www.senchalabs.org/connect/multipart.html) | ||
34 | + - [urlencoded](http://www.senchalabs.org/connect/urlencoded.html) | ||
35 | + - [cookieParser](http://www.senchalabs.org/connect/cookieParser.html) | ||
36 | + - [directory](http://www.senchalabs.org/connect/directory.html) | ||
37 | + - [compress](http://www.senchalabs.org/connect/compress.html) | ||
38 | + - [errorHandler](http://www.senchalabs.org/connect/errorHandler.html) | ||
39 | + - [favicon](http://www.senchalabs.org/connect/favicon.html) | ||
40 | + - [limit](http://www.senchalabs.org/connect/limit.html) | ||
41 | + - [logger](http://www.senchalabs.org/connect/logger.html) | ||
42 | + - [methodOverride](http://www.senchalabs.org/connect/methodOverride.html) | ||
43 | + - [query](http://www.senchalabs.org/connect/query.html) | ||
44 | + - [responseTime](http://www.senchalabs.org/connect/responseTime.html) | ||
45 | + - [session](http://www.senchalabs.org/connect/session.html) | ||
46 | + - [static](http://www.senchalabs.org/connect/static.html) | ||
47 | + - [staticCache](http://www.senchalabs.org/connect/staticCache.html) | ||
48 | + - [vhost](http://www.senchalabs.org/connect/vhost.html) | ||
49 | + - [subdomains](http://www.senchalabs.org/connect/subdomains.html) | ||
50 | + - [cookieSession](http://www.senchalabs.org/connect/cookieSession.html) | ||
51 | + | ||
52 | +## Running Tests | ||
53 | + | ||
54 | +first: | ||
55 | + | ||
56 | + $ npm install -d | ||
57 | + | ||
58 | +then: | ||
59 | + | ||
60 | + $ make test | ||
61 | + | ||
62 | +## Authors | ||
63 | + | ||
64 | + Below is the output from [git-summary](http://github.com/visionmedia/git-extras). | ||
65 | + | ||
66 | + | ||
67 | + project: connect | ||
68 | + commits: 2033 | ||
69 | + active : 301 days | ||
70 | + files : 171 | ||
71 | + authors: | ||
72 | + 1414 Tj Holowaychuk 69.6% | ||
73 | + 298 visionmedia 14.7% | ||
74 | + 191 Tim Caswell 9.4% | ||
75 | + 51 TJ Holowaychuk 2.5% | ||
76 | + 10 Ryan Olds 0.5% | ||
77 | + 8 Astro 0.4% | ||
78 | + 5 Nathan Rajlich 0.2% | ||
79 | + 5 Jakub Nešetřil 0.2% | ||
80 | + 3 Daniel Dickison 0.1% | ||
81 | + 3 David Rio Deiros 0.1% | ||
82 | + 3 Alexander Simmerl 0.1% | ||
83 | + 3 Andreas Lind Petersen 0.1% | ||
84 | + 2 Aaron Heckmann 0.1% | ||
85 | + 2 Jacques Crocker 0.1% | ||
86 | + 2 Fabian Jakobs 0.1% | ||
87 | + 2 Brian J Brennan 0.1% | ||
88 | + 2 Adam Malcontenti-Wilson 0.1% | ||
89 | + 2 Glen Mailer 0.1% | ||
90 | + 2 James Campos 0.1% | ||
91 | + 1 Trent Mick 0.0% | ||
92 | + 1 Troy Kruthoff 0.0% | ||
93 | + 1 Wei Zhu 0.0% | ||
94 | + 1 comerc 0.0% | ||
95 | + 1 darobin 0.0% | ||
96 | + 1 nateps 0.0% | ||
97 | + 1 Marco Sanson 0.0% | ||
98 | + 1 Arthur Taylor 0.0% | ||
99 | + 1 Aseem Kishore 0.0% | ||
100 | + 1 Bart Teeuwisse 0.0% | ||
101 | + 1 Cameron Howey 0.0% | ||
102 | + 1 Chad Weider 0.0% | ||
103 | + 1 Craig Barnes 0.0% | ||
104 | + 1 Eran Hammer-Lahav 0.0% | ||
105 | + 1 Gregory McWhirter 0.0% | ||
106 | + 1 Guillermo Rauch 0.0% | ||
107 | + 1 Jae Kwon 0.0% | ||
108 | + 1 Jakub Nesetril 0.0% | ||
109 | + 1 Joshua Peek 0.0% | ||
110 | + 1 Jxck 0.0% | ||
111 | + 1 AJ ONeal 0.0% | ||
112 | + 1 Michael Hemesath 0.0% | ||
113 | + 1 Morten Siebuhr 0.0% | ||
114 | + 1 Samori Gorse 0.0% | ||
115 | + 1 Tom Jensen 0.0% | ||
116 | + | ||
117 | +## Node Compatibility | ||
118 | + | ||
119 | + Connect `< 1.x` is compatible with node 0.2.x | ||
120 | + | ||
121 | + | ||
122 | + Connect `1.x` is compatible with node 0.4.x | ||
123 | + | ||
124 | + | ||
125 | + Connect (_master_) `2.x` is compatible with node 0.6.x | ||
126 | + | ||
127 | +## CLA | ||
128 | + | ||
129 | + [http://sencha.com/cla](http://sencha.com/cla) | ||
130 | + | ||
131 | +## License | ||
132 | + | ||
133 | +View the [LICENSE](https://github.com/senchalabs/connect/blob/master/LICENSE) file. The [Silk](http://www.famfamfam.com/lab/icons/silk/) icons used by the `directory` middleware created by/copyright of [FAMFAMFAM](http://www.famfamfam.com/). |
node_modules/connect/index.js
0 → 100644
node_modules/connect/lib/cache.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect - Cache | ||
4 | + * Copyright(c) 2011 Sencha Inc. | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Expose `Cache`. | ||
10 | + */ | ||
11 | + | ||
12 | +module.exports = Cache; | ||
13 | + | ||
14 | +/** | ||
15 | + * LRU cache store. | ||
16 | + * | ||
17 | + * @param {Number} limit | ||
18 | + * @api private | ||
19 | + */ | ||
20 | + | ||
21 | +function Cache(limit) { | ||
22 | + this.store = {}; | ||
23 | + this.keys = []; | ||
24 | + this.limit = limit; | ||
25 | +} | ||
26 | + | ||
27 | +/** | ||
28 | + * Touch `key`, promoting the object. | ||
29 | + * | ||
30 | + * @param {String} key | ||
31 | + * @param {Number} i | ||
32 | + * @api private | ||
33 | + */ | ||
34 | + | ||
35 | +Cache.prototype.touch = function(key, i){ | ||
36 | + this.keys.splice(i,1); | ||
37 | + this.keys.push(key); | ||
38 | +}; | ||
39 | + | ||
40 | +/** | ||
41 | + * Remove `key`. | ||
42 | + * | ||
43 | + * @param {String} key | ||
44 | + * @api private | ||
45 | + */ | ||
46 | + | ||
47 | +Cache.prototype.remove = function(key){ | ||
48 | + delete this.store[key]; | ||
49 | +}; | ||
50 | + | ||
51 | +/** | ||
52 | + * Get the object stored for `key`. | ||
53 | + * | ||
54 | + * @param {String} key | ||
55 | + * @return {Array} | ||
56 | + * @api private | ||
57 | + */ | ||
58 | + | ||
59 | +Cache.prototype.get = function(key){ | ||
60 | + return this.store[key]; | ||
61 | +}; | ||
62 | + | ||
63 | +/** | ||
64 | + * Add a cache `key`. | ||
65 | + * | ||
66 | + * @param {String} key | ||
67 | + * @return {Array} | ||
68 | + * @api private | ||
69 | + */ | ||
70 | + | ||
71 | +Cache.prototype.add = function(key){ | ||
72 | + // initialize store | ||
73 | + var len = this.keys.push(key); | ||
74 | + | ||
75 | + // limit reached, invalidate LRU | ||
76 | + if (len > this.limit) this.remove(this.keys.shift()); | ||
77 | + | ||
78 | + var arr = this.store[key] = []; | ||
79 | + arr.createdAt = new Date; | ||
80 | + return arr; | ||
81 | +}; |
node_modules/connect/lib/connect.js
0 → 100644
1 | +/*! | ||
2 | + * Connect | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var EventEmitter = require('events').EventEmitter | ||
13 | + , proto = require('./proto') | ||
14 | + , utils = require('./utils') | ||
15 | + , path = require('path') | ||
16 | + , basename = path.basename | ||
17 | + , fs = require('fs'); | ||
18 | + | ||
19 | +// node patches | ||
20 | + | ||
21 | +require('./patch'); | ||
22 | + | ||
23 | +// expose createServer() as the module | ||
24 | + | ||
25 | +exports = module.exports = createServer; | ||
26 | + | ||
27 | +/** | ||
28 | + * Framework version. | ||
29 | + */ | ||
30 | + | ||
31 | +exports.version = '2.7.11'; | ||
32 | + | ||
33 | +/** | ||
34 | + * Expose mime module. | ||
35 | + */ | ||
36 | + | ||
37 | +exports.mime = require('./middleware/static').mime; | ||
38 | + | ||
39 | +/** | ||
40 | + * Expose the prototype. | ||
41 | + */ | ||
42 | + | ||
43 | +exports.proto = proto; | ||
44 | + | ||
45 | +/** | ||
46 | + * Auto-load middleware getters. | ||
47 | + */ | ||
48 | + | ||
49 | +exports.middleware = {}; | ||
50 | + | ||
51 | +/** | ||
52 | + * Expose utilities. | ||
53 | + */ | ||
54 | + | ||
55 | +exports.utils = utils; | ||
56 | + | ||
57 | +/** | ||
58 | + * Create a new connect server. | ||
59 | + * | ||
60 | + * @return {Function} | ||
61 | + * @api public | ||
62 | + */ | ||
63 | + | ||
64 | +function createServer() { | ||
65 | + function app(req, res, next){ app.handle(req, res, next); } | ||
66 | + utils.merge(app, proto); | ||
67 | + utils.merge(app, EventEmitter.prototype); | ||
68 | + app.route = '/'; | ||
69 | + app.stack = []; | ||
70 | + for (var i = 0; i < arguments.length; ++i) { | ||
71 | + app.use(arguments[i]); | ||
72 | + } | ||
73 | + return app; | ||
74 | +}; | ||
75 | + | ||
76 | +/** | ||
77 | + * Support old `.createServer()` method. | ||
78 | + */ | ||
79 | + | ||
80 | +createServer.createServer = createServer; | ||
81 | + | ||
82 | +/** | ||
83 | + * Auto-load bundled middleware with getters. | ||
84 | + */ | ||
85 | + | ||
86 | +fs.readdirSync(__dirname + '/middleware').forEach(function(filename){ | ||
87 | + if (!/\.js$/.test(filename)) return; | ||
88 | + var name = basename(filename, '.js'); | ||
89 | + function load(){ return require('./middleware/' + name); } | ||
90 | + exports.middleware.__defineGetter__(name, load); | ||
91 | + exports.__defineGetter__(name, load); | ||
92 | +}); |
node_modules/connect/lib/index.js
0 → 100644
1 | + | ||
2 | +/** | ||
3 | + * Connect is a middleware framework for node, | ||
4 | + * shipping with over 18 bundled middleware and a rich selection of | ||
5 | + * 3rd-party middleware. | ||
6 | + * | ||
7 | + * var app = connect() | ||
8 | + * .use(connect.logger('dev')) | ||
9 | + * .use(connect.static('public')) | ||
10 | + * .use(function(req, res){ | ||
11 | + * res.end('hello world\n'); | ||
12 | + * }) | ||
13 | + * .listen(3000); | ||
14 | + * | ||
15 | + * Installation: | ||
16 | + * | ||
17 | + * $ npm install connect | ||
18 | + * | ||
19 | + * Middleware: | ||
20 | + * | ||
21 | + * - [logger](logger.html) request logger with custom format support | ||
22 | + * - [csrf](csrf.html) Cross-site request forgery protection | ||
23 | + * - [compress](compress.html) Gzip compression middleware | ||
24 | + * - [basicAuth](basicAuth.html) basic http authentication | ||
25 | + * - [bodyParser](bodyParser.html) extensible request body parser | ||
26 | + * - [json](json.html) application/json parser | ||
27 | + * - [urlencoded](urlencoded.html) application/x-www-form-urlencoded parser | ||
28 | + * - [multipart](multipart.html) multipart/form-data parser | ||
29 | + * - [timeout](timeout.html) request timeouts | ||
30 | + * - [cookieParser](cookieParser.html) cookie parser | ||
31 | + * - [session](session.html) session management support with bundled MemoryStore | ||
32 | + * - [cookieSession](cookieSession.html) cookie-based session support | ||
33 | + * - [methodOverride](methodOverride.html) faux HTTP method support | ||
34 | + * - [responseTime](responseTime.html) calculates response-time and exposes via X-Response-Time | ||
35 | + * - [staticCache](staticCache.html) memory cache layer for the static() middleware | ||
36 | + * - [static](static.html) streaming static file server supporting `Range` and more | ||
37 | + * - [directory](directory.html) directory listing middleware | ||
38 | + * - [vhost](vhost.html) virtual host sub-domain mapping middleware | ||
39 | + * - [favicon](favicon.html) efficient favicon server (with default icon) | ||
40 | + * - [limit](limit.html) limit the bytesize of request bodies | ||
41 | + * - [query](query.html) automatic querystring parser, populating `req.query` | ||
42 | + * - [errorHandler](errorHandler.html) flexible error handler | ||
43 | + * | ||
44 | + * Links: | ||
45 | + * | ||
46 | + * - list of [3rd-party](https://github.com/senchalabs/connect/wiki) middleware | ||
47 | + * - GitHub [repository](http://github.com/senchalabs/connect) | ||
48 | + * - [test documentation](https://github.com/senchalabs/connect/blob/gh-pages/tests.md) | ||
49 | + * | ||
50 | + */ | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - basicAuth | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('../utils') | ||
14 | + , unauthorized = utils.unauthorized; | ||
15 | + | ||
16 | +/** | ||
17 | + * Basic Auth: | ||
18 | + * | ||
19 | + * Enfore basic authentication by providing a `callback(user, pass)`, | ||
20 | + * which must return `true` in order to gain access. Alternatively an async | ||
21 | + * method is provided as well, invoking `callback(user, pass, callback)`. Populates | ||
22 | + * `req.user`. The final alternative is simply passing username / password | ||
23 | + * strings. | ||
24 | + * | ||
25 | + * Simple username and password | ||
26 | + * | ||
27 | + * connect(connect.basicAuth('username', 'password')); | ||
28 | + * | ||
29 | + * Callback verification | ||
30 | + * | ||
31 | + * connect() | ||
32 | + * .use(connect.basicAuth(function(user, pass){ | ||
33 | + * return 'tj' == user & 'wahoo' == pass; | ||
34 | + * })) | ||
35 | + * | ||
36 | + * Async callback verification, accepting `fn(err, user)`. | ||
37 | + * | ||
38 | + * connect() | ||
39 | + * .use(connect.basicAuth(function(user, pass, fn){ | ||
40 | + * User.authenticate({ user: user, pass: pass }, fn); | ||
41 | + * })) | ||
42 | + * | ||
43 | + * @param {Function|String} callback or username | ||
44 | + * @param {String} realm | ||
45 | + * @api public | ||
46 | + */ | ||
47 | + | ||
48 | +module.exports = function basicAuth(callback, realm) { | ||
49 | + var username, password; | ||
50 | + | ||
51 | + // user / pass strings | ||
52 | + if ('string' == typeof callback) { | ||
53 | + username = callback; | ||
54 | + password = realm; | ||
55 | + if ('string' != typeof password) throw new Error('password argument required'); | ||
56 | + realm = arguments[2]; | ||
57 | + callback = function(user, pass){ | ||
58 | + return user == username && pass == password; | ||
59 | + } | ||
60 | + } | ||
61 | + | ||
62 | + realm = realm || 'Authorization Required'; | ||
63 | + | ||
64 | + return function(req, res, next) { | ||
65 | + var authorization = req.headers.authorization; | ||
66 | + | ||
67 | + if (req.user) return next(); | ||
68 | + if (!authorization) return unauthorized(res, realm); | ||
69 | + | ||
70 | + var parts = authorization.split(' '); | ||
71 | + | ||
72 | + if (parts.length !== 2) return next(utils.error(400)); | ||
73 | + | ||
74 | + var scheme = parts[0] | ||
75 | + , credentials = new Buffer(parts[1], 'base64').toString() | ||
76 | + , index = credentials.indexOf(':'); | ||
77 | + | ||
78 | + if ('Basic' != scheme || index < 0) return next(utils.error(400)); | ||
79 | + | ||
80 | + var user = credentials.slice(0, index) | ||
81 | + , pass = credentials.slice(index + 1); | ||
82 | + | ||
83 | + // async | ||
84 | + if (callback.length >= 3) { | ||
85 | + var pause = utils.pause(req); | ||
86 | + callback(user, pass, function(err, user){ | ||
87 | + if (err || !user) return unauthorized(res, realm); | ||
88 | + req.user = req.remoteUser = user; | ||
89 | + next(); | ||
90 | + pause.resume(); | ||
91 | + }); | ||
92 | + // sync | ||
93 | + } else { | ||
94 | + if (callback(user, pass)) { | ||
95 | + req.user = req.remoteUser = user; | ||
96 | + next(); | ||
97 | + } else { | ||
98 | + unauthorized(res, realm); | ||
99 | + } | ||
100 | + } | ||
101 | + } | ||
102 | +}; | ||
103 | + |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - bodyParser | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var multipart = require('./multipart') | ||
14 | + , urlencoded = require('./urlencoded') | ||
15 | + , json = require('./json'); | ||
16 | + | ||
17 | +/** | ||
18 | + * Body parser: | ||
19 | + * | ||
20 | + * Parse request bodies, supports _application/json_, | ||
21 | + * _application/x-www-form-urlencoded_, and _multipart/form-data_. | ||
22 | + * | ||
23 | + * This is equivalent to: | ||
24 | + * | ||
25 | + * app.use(connect.json()); | ||
26 | + * app.use(connect.urlencoded()); | ||
27 | + * app.use(connect.multipart()); | ||
28 | + * | ||
29 | + * Examples: | ||
30 | + * | ||
31 | + * connect() | ||
32 | + * .use(connect.bodyParser()) | ||
33 | + * .use(function(req, res) { | ||
34 | + * res.end('viewing user ' + req.body.user.name); | ||
35 | + * }); | ||
36 | + * | ||
37 | + * $ curl -d 'user[name]=tj' http://local/ | ||
38 | + * $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/ | ||
39 | + * | ||
40 | + * View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info. | ||
41 | + * | ||
42 | + * @param {Object} options | ||
43 | + * @return {Function} | ||
44 | + * @api public | ||
45 | + */ | ||
46 | + | ||
47 | +exports = module.exports = function bodyParser(options){ | ||
48 | + var _urlencoded = urlencoded(options) | ||
49 | + , _multipart = multipart(options) | ||
50 | + , _json = json(options); | ||
51 | + | ||
52 | + return function bodyParser(req, res, next) { | ||
53 | + _json(req, res, function(err){ | ||
54 | + if (err) return next(err); | ||
55 | + _urlencoded(req, res, function(err){ | ||
56 | + if (err) return next(err); | ||
57 | + _multipart(req, res, next); | ||
58 | + }); | ||
59 | + }); | ||
60 | + } | ||
61 | +}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/*! | ||
2 | + * Connect - compress | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var zlib = require('zlib'); | ||
13 | +var utils = require('../utils'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Supported content-encoding methods. | ||
17 | + */ | ||
18 | + | ||
19 | +exports.methods = { | ||
20 | + gzip: zlib.createGzip | ||
21 | + , deflate: zlib.createDeflate | ||
22 | +}; | ||
23 | + | ||
24 | +/** | ||
25 | + * Default filter function. | ||
26 | + */ | ||
27 | + | ||
28 | +exports.filter = function(req, res){ | ||
29 | + return /json|text|javascript|dart|image\/svg\+xml|application\/x-font-ttf|application\/vnd\.ms-opentype|application\/vnd\.ms-fontobject/.test(res.getHeader('Content-Type')); | ||
30 | +}; | ||
31 | + | ||
32 | +/** | ||
33 | + * Compress: | ||
34 | + * | ||
35 | + * Compress response data with gzip/deflate. | ||
36 | + * | ||
37 | + * Filter: | ||
38 | + * | ||
39 | + * A `filter` callback function may be passed to | ||
40 | + * replace the default logic of: | ||
41 | + * | ||
42 | + * exports.filter = function(req, res){ | ||
43 | + * return /json|text|javascript/.test(res.getHeader('Content-Type')); | ||
44 | + * }; | ||
45 | + * | ||
46 | + * Threshold: | ||
47 | + * | ||
48 | + * Only compress the response if the byte size is at or above a threshold. | ||
49 | + * Always compress while streaming. | ||
50 | + * | ||
51 | + * - `threshold` - string representation of size or bytes as an integer. | ||
52 | + * | ||
53 | + * Options: | ||
54 | + * | ||
55 | + * All remaining options are passed to the gzip/deflate | ||
56 | + * creation functions. Consult node's docs for additional details. | ||
57 | + * | ||
58 | + * - `chunkSize` (default: 16*1024) | ||
59 | + * - `windowBits` | ||
60 | + * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression | ||
61 | + * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more | ||
62 | + * - `strategy`: compression strategy | ||
63 | + * | ||
64 | + * @param {Object} options | ||
65 | + * @return {Function} | ||
66 | + * @api public | ||
67 | + */ | ||
68 | + | ||
69 | +module.exports = function compress(options) { | ||
70 | + options = options || {}; | ||
71 | + var names = Object.keys(exports.methods) | ||
72 | + , filter = options.filter || exports.filter | ||
73 | + , threshold; | ||
74 | + | ||
75 | + if (false === options.threshold || 0 === options.threshold) { | ||
76 | + threshold = 0 | ||
77 | + } else if ('string' === typeof options.threshold) { | ||
78 | + threshold = utils.parseBytes(options.threshold) | ||
79 | + } else { | ||
80 | + threshold = options.threshold || 1024 | ||
81 | + } | ||
82 | + | ||
83 | + return function compress(req, res, next){ | ||
84 | + var accept = req.headers['accept-encoding'] | ||
85 | + , vary = res.getHeader('Vary') | ||
86 | + , write = res.write | ||
87 | + , end = res.end | ||
88 | + , compress = true | ||
89 | + , stream | ||
90 | + , method; | ||
91 | + | ||
92 | + // vary | ||
93 | + if (!vary) { | ||
94 | + res.setHeader('Vary', 'Accept-Encoding'); | ||
95 | + } else if (!~vary.indexOf('Accept-Encoding')) { | ||
96 | + res.setHeader('Vary', vary + ', Accept-Encoding'); | ||
97 | + } | ||
98 | + | ||
99 | + // see #724 | ||
100 | + req.on('close', function(){ | ||
101 | + res.write = res.end = function(){}; | ||
102 | + }); | ||
103 | + | ||
104 | + // proxy | ||
105 | + | ||
106 | + res.write = function(chunk, encoding){ | ||
107 | + if (!this.headerSent) this._implicitHeader(); | ||
108 | + return stream | ||
109 | + ? stream.write(new Buffer(chunk, encoding)) | ||
110 | + : write.call(res, chunk, encoding); | ||
111 | + }; | ||
112 | + | ||
113 | + res.end = function(chunk, encoding){ | ||
114 | + if (chunk) { | ||
115 | + if (!this.headerSent && getSize(chunk) < threshold) compress = false; | ||
116 | + this.write(chunk, encoding); | ||
117 | + } else if (!this.headerSent) { | ||
118 | + // response size === 0 | ||
119 | + compress = false; | ||
120 | + } | ||
121 | + return stream | ||
122 | + ? stream.end() | ||
123 | + : end.call(res); | ||
124 | + }; | ||
125 | + | ||
126 | + res.on('header', function(){ | ||
127 | + if (!compress) return; | ||
128 | + | ||
129 | + var encoding = res.getHeader('Content-Encoding') || 'identity'; | ||
130 | + | ||
131 | + // already encoded | ||
132 | + if ('identity' != encoding) return; | ||
133 | + | ||
134 | + // default request filter | ||
135 | + if (!filter(req, res)) return; | ||
136 | + | ||
137 | + // SHOULD use identity | ||
138 | + if (!accept) return; | ||
139 | + | ||
140 | + // head | ||
141 | + if ('HEAD' == req.method) return; | ||
142 | + | ||
143 | + // default to gzip | ||
144 | + if ('*' == accept.trim()) method = 'gzip'; | ||
145 | + | ||
146 | + // compression method | ||
147 | + if (!method) { | ||
148 | + for (var i = 0, len = names.length; i < len; ++i) { | ||
149 | + if (~accept.indexOf(names[i])) { | ||
150 | + method = names[i]; | ||
151 | + break; | ||
152 | + } | ||
153 | + } | ||
154 | + } | ||
155 | + | ||
156 | + // compression method | ||
157 | + if (!method) return; | ||
158 | + | ||
159 | + // compression stream | ||
160 | + stream = exports.methods[method](options); | ||
161 | + | ||
162 | + // header fields | ||
163 | + res.setHeader('Content-Encoding', method); | ||
164 | + res.removeHeader('Content-Length'); | ||
165 | + | ||
166 | + // compression | ||
167 | + | ||
168 | + stream.on('data', function(chunk){ | ||
169 | + write.call(res, chunk); | ||
170 | + }); | ||
171 | + | ||
172 | + stream.on('end', function(){ | ||
173 | + end.call(res); | ||
174 | + }); | ||
175 | + | ||
176 | + stream.on('drain', function() { | ||
177 | + res.emit('drain'); | ||
178 | + }); | ||
179 | + }); | ||
180 | + | ||
181 | + next(); | ||
182 | + }; | ||
183 | +}; | ||
184 | + | ||
185 | +function getSize(chunk) { | ||
186 | + return Buffer.isBuffer(chunk) | ||
187 | + ? chunk.length | ||
188 | + : Buffer.byteLength(chunk); | ||
189 | +} |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - cookieParser | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('./../utils') | ||
14 | + , cookie = require('cookie'); | ||
15 | + | ||
16 | +/** | ||
17 | + * Cookie parser: | ||
18 | + * | ||
19 | + * Parse _Cookie_ header and populate `req.cookies` | ||
20 | + * with an object keyed by the cookie names. Optionally | ||
21 | + * you may enabled signed cookie support by passing | ||
22 | + * a `secret` string, which assigns `req.secret` so | ||
23 | + * it may be used by other middleware. | ||
24 | + * | ||
25 | + * Examples: | ||
26 | + * | ||
27 | + * connect() | ||
28 | + * .use(connect.cookieParser('optional secret string')) | ||
29 | + * .use(function(req, res, next){ | ||
30 | + * res.end(JSON.stringify(req.cookies)); | ||
31 | + * }) | ||
32 | + * | ||
33 | + * @param {String} secret | ||
34 | + * @return {Function} | ||
35 | + * @api public | ||
36 | + */ | ||
37 | + | ||
38 | +module.exports = function cookieParser(secret){ | ||
39 | + return function cookieParser(req, res, next) { | ||
40 | + if (req.cookies) return next(); | ||
41 | + var cookies = req.headers.cookie; | ||
42 | + | ||
43 | + req.secret = secret; | ||
44 | + req.cookies = {}; | ||
45 | + req.signedCookies = {}; | ||
46 | + | ||
47 | + if (cookies) { | ||
48 | + try { | ||
49 | + req.cookies = cookie.parse(cookies); | ||
50 | + if (secret) { | ||
51 | + req.signedCookies = utils.parseSignedCookies(req.cookies, secret); | ||
52 | + req.signedCookies = utils.parseJSONCookies(req.signedCookies); | ||
53 | + } | ||
54 | + req.cookies = utils.parseJSONCookies(req.cookies); | ||
55 | + } catch (err) { | ||
56 | + err.status = 400; | ||
57 | + return next(err); | ||
58 | + } | ||
59 | + } | ||
60 | + next(); | ||
61 | + }; | ||
62 | +}; |
1 | +/*! | ||
2 | + * Connect - cookieSession | ||
3 | + * Copyright(c) 2011 Sencha Inc. | ||
4 | + * MIT Licensed | ||
5 | + */ | ||
6 | + | ||
7 | +/** | ||
8 | + * Module dependencies. | ||
9 | + */ | ||
10 | + | ||
11 | +var utils = require('./../utils') | ||
12 | + , Cookie = require('./session/cookie') | ||
13 | + , debug = require('debug')('connect:cookieSession') | ||
14 | + , signature = require('cookie-signature') | ||
15 | + , crc32 = require('buffer-crc32'); | ||
16 | + | ||
17 | +/** | ||
18 | + * Cookie Session: | ||
19 | + * | ||
20 | + * Cookie session middleware. | ||
21 | + * | ||
22 | + * var app = connect(); | ||
23 | + * app.use(connect.cookieParser()); | ||
24 | + * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }})); | ||
25 | + * | ||
26 | + * Options: | ||
27 | + * | ||
28 | + * - `key` cookie name defaulting to `connect.sess` | ||
29 | + * - `secret` prevents cookie tampering | ||
30 | + * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }` | ||
31 | + * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto") | ||
32 | + * | ||
33 | + * Clearing sessions: | ||
34 | + * | ||
35 | + * To clear the session simply set its value to `null`, | ||
36 | + * `cookieSession()` will then respond with a 1970 Set-Cookie. | ||
37 | + * | ||
38 | + * req.session = null; | ||
39 | + * | ||
40 | + * @param {Object} options | ||
41 | + * @return {Function} | ||
42 | + * @api public | ||
43 | + */ | ||
44 | + | ||
45 | +module.exports = function cookieSession(options){ | ||
46 | + // TODO: utilize Session/Cookie to unify API | ||
47 | + options = options || {}; | ||
48 | + var key = options.key || 'connect.sess' | ||
49 | + , trustProxy = options.proxy; | ||
50 | + | ||
51 | + return function cookieSession(req, res, next) { | ||
52 | + | ||
53 | + // req.secret is for backwards compatibility | ||
54 | + var secret = options.secret || req.secret; | ||
55 | + if (!secret) throw new Error('`secret` option required for cookie sessions'); | ||
56 | + | ||
57 | + // default session | ||
58 | + req.session = {}; | ||
59 | + var cookie = req.session.cookie = new Cookie(options.cookie); | ||
60 | + | ||
61 | + // pathname mismatch | ||
62 | + if (0 != req.originalUrl.indexOf(cookie.path)) return next(); | ||
63 | + | ||
64 | + // cookieParser secret | ||
65 | + if (!options.secret && req.secret) { | ||
66 | + req.session = req.signedCookies[key] || {}; | ||
67 | + req.session.cookie = cookie; | ||
68 | + } else { | ||
69 | + // TODO: refactor | ||
70 | + var rawCookie = req.cookies[key]; | ||
71 | + if (rawCookie) { | ||
72 | + var unsigned = utils.parseSignedCookie(rawCookie, secret); | ||
73 | + if (unsigned) { | ||
74 | + var originalHash = crc32.signed(unsigned); | ||
75 | + req.session = utils.parseJSONCookie(unsigned) || {}; | ||
76 | + req.session.cookie = cookie; | ||
77 | + } | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + res.on('header', function(){ | ||
82 | + // removed | ||
83 | + if (!req.session) { | ||
84 | + debug('clear session'); | ||
85 | + cookie.expires = new Date(0); | ||
86 | + res.setHeader('Set-Cookie', cookie.serialize(key, '')); | ||
87 | + return; | ||
88 | + } | ||
89 | + | ||
90 | + delete req.session.cookie; | ||
91 | + | ||
92 | + // check security | ||
93 | + var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase() | ||
94 | + , tls = req.connection.encrypted || (trustProxy && 'https' == proto.split(/\s*,\s*/)[0]); | ||
95 | + | ||
96 | + // only send secure cookies via https | ||
97 | + if (cookie.secure && !tls) return debug('not secured'); | ||
98 | + | ||
99 | + // serialize | ||
100 | + debug('serializing %j', req.session); | ||
101 | + var val = 'j:' + JSON.stringify(req.session); | ||
102 | + | ||
103 | + // compare hashes, no need to set-cookie if unchanged | ||
104 | + if (originalHash == crc32.signed(val)) return debug('unmodified session'); | ||
105 | + | ||
106 | + // set-cookie | ||
107 | + val = 's:' + signature.sign(val, secret); | ||
108 | + val = cookie.serialize(key, val); | ||
109 | + debug('set-cookie %j', cookie); | ||
110 | + res.setHeader('Set-Cookie', val); | ||
111 | + }); | ||
112 | + | ||
113 | + next(); | ||
114 | + }; | ||
115 | +}; |
node_modules/connect/lib/middleware/csrf.js
0 → 100644
1 | +/*! | ||
2 | + * Connect - csrf | ||
3 | + * Copyright(c) 2011 Sencha Inc. | ||
4 | + * MIT Licensed | ||
5 | + */ | ||
6 | + | ||
7 | +/** | ||
8 | + * Module dependencies. | ||
9 | + */ | ||
10 | + | ||
11 | +var utils = require('../utils'); | ||
12 | +var uid = require('uid2'); | ||
13 | +var crypto = require('crypto'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Anti CSRF: | ||
17 | + * | ||
18 | + * CSRF protection middleware. | ||
19 | + * | ||
20 | + * This middleware adds a `req.csrfToken()` function to make a token | ||
21 | + * which should be added to requests which mutate | ||
22 | + * state, within a hidden form field, query-string etc. This | ||
23 | + * token is validated against the visitor's session. | ||
24 | + * | ||
25 | + * The default `value` function checks `req.body` generated | ||
26 | + * by the `bodyParser()` middleware, `req.query` generated | ||
27 | + * by `query()`, and the "X-CSRF-Token" header field. | ||
28 | + * | ||
29 | + * This middleware requires session support, thus should be added | ||
30 | + * somewhere _below_ `session()` and `cookieParser()`. | ||
31 | + * | ||
32 | + * Options: | ||
33 | + * | ||
34 | + * - `value` a function accepting the request, returning the token | ||
35 | + * | ||
36 | + * @param {Object} options | ||
37 | + * @api public | ||
38 | + */ | ||
39 | + | ||
40 | +module.exports = function csrf(options) { | ||
41 | + options = options || {}; | ||
42 | + var value = options.value || defaultValue; | ||
43 | + | ||
44 | + return function(req, res, next){ | ||
45 | + | ||
46 | + // already have one | ||
47 | + var secret = req.session._csrfSecret; | ||
48 | + if (secret) return createToken(secret); | ||
49 | + | ||
50 | + // generate secret | ||
51 | + uid(24, function(err, secret){ | ||
52 | + if (err) return next(err); | ||
53 | + req.session._csrfSecret = secret; | ||
54 | + createToken(secret); | ||
55 | + }); | ||
56 | + | ||
57 | + // generate the token | ||
58 | + function createToken(secret) { | ||
59 | + var token; | ||
60 | + | ||
61 | + // lazy-load token | ||
62 | + req.csrfToken = function csrfToken() { | ||
63 | + return token || (token = saltedToken(secret)); | ||
64 | + }; | ||
65 | + | ||
66 | + // compatibility with old middleware | ||
67 | + Object.defineProperty(req.session, '_csrf', { | ||
68 | + configurable: true, | ||
69 | + get: function() { | ||
70 | + console.warn('req.session._csrf is deprecated, use req.csrfToken([callback]) instead'); | ||
71 | + return req.csrfToken(); | ||
72 | + } | ||
73 | + }); | ||
74 | + | ||
75 | + // ignore these methods | ||
76 | + if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next(); | ||
77 | + | ||
78 | + // determine user-submitted value | ||
79 | + var val = value(req); | ||
80 | + | ||
81 | + // check | ||
82 | + if (!checkToken(val, secret)) return next(utils.error(403)); | ||
83 | + | ||
84 | + next(); | ||
85 | + } | ||
86 | + } | ||
87 | +}; | ||
88 | + | ||
89 | +/** | ||
90 | + * Default value function, checking the `req.body` | ||
91 | + * and `req.query` for the CSRF token. | ||
92 | + * | ||
93 | + * @param {IncomingMessage} req | ||
94 | + * @return {String} | ||
95 | + * @api private | ||
96 | + */ | ||
97 | + | ||
98 | +function defaultValue(req) { | ||
99 | + return (req.body && req.body._csrf) | ||
100 | + || (req.query && req.query._csrf) | ||
101 | + || (req.headers['x-csrf-token']) | ||
102 | + || (req.headers['x-xsrf-token']); | ||
103 | +} | ||
104 | + | ||
105 | +/** | ||
106 | + * Return salted token. | ||
107 | + * | ||
108 | + * @param {String} secret | ||
109 | + * @return {String} | ||
110 | + * @api private | ||
111 | + */ | ||
112 | + | ||
113 | +function saltedToken(secret) { | ||
114 | + return createToken(generateSalt(10), secret); | ||
115 | +} | ||
116 | + | ||
117 | +/** | ||
118 | + * Creates a CSRF token from a given salt and secret. | ||
119 | + * | ||
120 | + * @param {String} salt (should be 10 characters) | ||
121 | + * @param {String} secret | ||
122 | + * @return {String} | ||
123 | + * @api private | ||
124 | + */ | ||
125 | + | ||
126 | +function createToken(salt, secret) { | ||
127 | + return salt + crypto | ||
128 | + .createHash('sha1') | ||
129 | + .update(salt + secret) | ||
130 | + .digest('base64'); | ||
131 | +} | ||
132 | + | ||
133 | +/** | ||
134 | + * Checks if a given CSRF token matches the given secret. | ||
135 | + * | ||
136 | + * @param {String} token | ||
137 | + * @param {String} secret | ||
138 | + * @return {Boolean} | ||
139 | + * @api private | ||
140 | + */ | ||
141 | + | ||
142 | +function checkToken(token, secret) { | ||
143 | + if ('string' != typeof token) return false; | ||
144 | + return token === createToken(token.slice(0, 10), secret); | ||
145 | +} | ||
146 | + | ||
147 | +/** | ||
148 | + * Generates a random salt, using a fast non-blocking PRNG (Math.random()). | ||
149 | + * | ||
150 | + * @param {Number} length | ||
151 | + * @return {String} | ||
152 | + * @api private | ||
153 | + */ | ||
154 | + | ||
155 | +function generateSalt(length) { | ||
156 | + var i, r = []; | ||
157 | + for (i = 0; i < length; ++i) { | ||
158 | + r.push(SALTCHARS[Math.floor(Math.random() * SALTCHARS.length)]); | ||
159 | + } | ||
160 | + return r.join(''); | ||
161 | +} | ||
162 | + | ||
163 | +var SALTCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - directory | ||
4 | + * Copyright(c) 2011 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +// TODO: icon / style for directories | ||
10 | +// TODO: arrow key navigation | ||
11 | +// TODO: make icons extensible | ||
12 | + | ||
13 | +/** | ||
14 | + * Module dependencies. | ||
15 | + */ | ||
16 | + | ||
17 | +var fs = require('fs') | ||
18 | + , parse = require('url').parse | ||
19 | + , utils = require('../utils') | ||
20 | + , path = require('path') | ||
21 | + , normalize = path.normalize | ||
22 | + , extname = path.extname | ||
23 | + , join = path.join; | ||
24 | + | ||
25 | +/*! | ||
26 | + * Icon cache. | ||
27 | + */ | ||
28 | + | ||
29 | +var cache = {}; | ||
30 | + | ||
31 | +/** | ||
32 | + * Directory: | ||
33 | + * | ||
34 | + * Serve directory listings with the given `root` path. | ||
35 | + * | ||
36 | + * Options: | ||
37 | + * | ||
38 | + * - `hidden` display hidden (dot) files. Defaults to false. | ||
39 | + * - `icons` display icons. Defaults to false. | ||
40 | + * - `filter` Apply this filter function to files. Defaults to false. | ||
41 | + * | ||
42 | + * @param {String} root | ||
43 | + * @param {Object} options | ||
44 | + * @return {Function} | ||
45 | + * @api public | ||
46 | + */ | ||
47 | + | ||
48 | +exports = module.exports = function directory(root, options){ | ||
49 | + options = options || {}; | ||
50 | + | ||
51 | + // root required | ||
52 | + if (!root) throw new Error('directory() root path required'); | ||
53 | + var hidden = options.hidden | ||
54 | + , icons = options.icons | ||
55 | + , filter = options.filter | ||
56 | + , root = normalize(root); | ||
57 | + | ||
58 | + return function directory(req, res, next) { | ||
59 | + if ('GET' != req.method && 'HEAD' != req.method) return next(); | ||
60 | + | ||
61 | + var accept = req.headers.accept || 'text/plain' | ||
62 | + , url = parse(req.url) | ||
63 | + , dir = decodeURIComponent(url.pathname) | ||
64 | + , path = normalize(join(root, dir)) | ||
65 | + , originalUrl = parse(req.originalUrl) | ||
66 | + , originalDir = decodeURIComponent(originalUrl.pathname) | ||
67 | + , showUp = path != root && path != root + '/'; | ||
68 | + | ||
69 | + // null byte(s), bad request | ||
70 | + if (~path.indexOf('\0')) return next(utils.error(400)); | ||
71 | + | ||
72 | + // malicious path, forbidden | ||
73 | + if (0 != path.indexOf(root)) return next(utils.error(403)); | ||
74 | + | ||
75 | + // check if we have a directory | ||
76 | + fs.stat(path, function(err, stat){ | ||
77 | + if (err) return 'ENOENT' == err.code | ||
78 | + ? next() | ||
79 | + : next(err); | ||
80 | + | ||
81 | + if (!stat.isDirectory()) return next(); | ||
82 | + | ||
83 | + // fetch files | ||
84 | + fs.readdir(path, function(err, files){ | ||
85 | + if (err) return next(err); | ||
86 | + if (!hidden) files = removeHidden(files); | ||
87 | + if (filter) files = files.filter(filter); | ||
88 | + files.sort(); | ||
89 | + | ||
90 | + // content-negotiation | ||
91 | + for (var key in exports) { | ||
92 | + if (~accept.indexOf(key) || ~accept.indexOf('*/*')) { | ||
93 | + exports[key](req, res, files, next, originalDir, showUp, icons); | ||
94 | + return; | ||
95 | + } | ||
96 | + } | ||
97 | + | ||
98 | + // not acceptable | ||
99 | + next(utils.error(406)); | ||
100 | + }); | ||
101 | + }); | ||
102 | + }; | ||
103 | +}; | ||
104 | + | ||
105 | +/** | ||
106 | + * Respond with text/html. | ||
107 | + */ | ||
108 | + | ||
109 | +exports.html = function(req, res, files, next, dir, showUp, icons){ | ||
110 | + fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){ | ||
111 | + if (err) return next(err); | ||
112 | + fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){ | ||
113 | + if (err) return next(err); | ||
114 | + if (showUp) files.unshift('..'); | ||
115 | + str = str | ||
116 | + .replace('{style}', style) | ||
117 | + .replace('{files}', html(files, dir, icons)) | ||
118 | + .replace('{directory}', dir) | ||
119 | + .replace('{linked-path}', htmlPath(dir)); | ||
120 | + res.setHeader('Content-Type', 'text/html'); | ||
121 | + res.setHeader('Content-Length', str.length); | ||
122 | + res.end(str); | ||
123 | + }); | ||
124 | + }); | ||
125 | +}; | ||
126 | + | ||
127 | +/** | ||
128 | + * Respond with application/json. | ||
129 | + */ | ||
130 | + | ||
131 | +exports.json = function(req, res, files){ | ||
132 | + files = JSON.stringify(files); | ||
133 | + res.setHeader('Content-Type', 'application/json'); | ||
134 | + res.setHeader('Content-Length', files.length); | ||
135 | + res.end(files); | ||
136 | +}; | ||
137 | + | ||
138 | +/** | ||
139 | + * Respond with text/plain. | ||
140 | + */ | ||
141 | + | ||
142 | +exports.plain = function(req, res, files){ | ||
143 | + files = files.join('\n') + '\n'; | ||
144 | + res.setHeader('Content-Type', 'text/plain'); | ||
145 | + res.setHeader('Content-Length', files.length); | ||
146 | + res.end(files); | ||
147 | +}; | ||
148 | + | ||
149 | +/** | ||
150 | + * Map html `dir`, returning a linked path. | ||
151 | + */ | ||
152 | + | ||
153 | +function htmlPath(dir) { | ||
154 | + var curr = []; | ||
155 | + return dir.split('/').map(function(part){ | ||
156 | + curr.push(part); | ||
157 | + return '<a href="' + curr.join('/') + '">' + part + '</a>'; | ||
158 | + }).join(' / '); | ||
159 | +} | ||
160 | + | ||
161 | +/** | ||
162 | + * Map html `files`, returning an html unordered list. | ||
163 | + */ | ||
164 | + | ||
165 | +function html(files, dir, useIcons) { | ||
166 | + return '<ul id="files">' + files.map(function(file){ | ||
167 | + var icon = '' | ||
168 | + , classes = []; | ||
169 | + | ||
170 | + if (useIcons && '..' != file) { | ||
171 | + icon = icons[extname(file)] || icons.default; | ||
172 | + icon = '<img src="data:image/png;base64,' + load(icon) + '" />'; | ||
173 | + classes.push('icon'); | ||
174 | + } | ||
175 | + | ||
176 | + return '<li><a href="' | ||
177 | + + join(dir, file) | ||
178 | + + '" class="' | ||
179 | + + classes.join(' ') + '"' | ||
180 | + + ' title="' + file + '">' | ||
181 | + + icon + file + '</a></li>'; | ||
182 | + | ||
183 | + }).join('\n') + '</ul>'; | ||
184 | +} | ||
185 | + | ||
186 | +/** | ||
187 | + * Load and cache the given `icon`. | ||
188 | + * | ||
189 | + * @param {String} icon | ||
190 | + * @return {String} | ||
191 | + * @api private | ||
192 | + */ | ||
193 | + | ||
194 | +function load(icon) { | ||
195 | + if (cache[icon]) return cache[icon]; | ||
196 | + return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64'); | ||
197 | +} | ||
198 | + | ||
199 | +/** | ||
200 | + * Filter "hidden" `files`, aka files | ||
201 | + * beginning with a `.`. | ||
202 | + * | ||
203 | + * @param {Array} files | ||
204 | + * @return {Array} | ||
205 | + * @api private | ||
206 | + */ | ||
207 | + | ||
208 | +function removeHidden(files) { | ||
209 | + return files.filter(function(file){ | ||
210 | + return '.' != file[0]; | ||
211 | + }); | ||
212 | +} | ||
213 | + | ||
214 | +/** | ||
215 | + * Icon map. | ||
216 | + */ | ||
217 | + | ||
218 | +var icons = { | ||
219 | + '.js': 'page_white_code_red.png' | ||
220 | + , '.c': 'page_white_c.png' | ||
221 | + , '.h': 'page_white_h.png' | ||
222 | + , '.cc': 'page_white_cplusplus.png' | ||
223 | + , '.php': 'page_white_php.png' | ||
224 | + , '.rb': 'page_white_ruby.png' | ||
225 | + , '.cpp': 'page_white_cplusplus.png' | ||
226 | + , '.swf': 'page_white_flash.png' | ||
227 | + , '.pdf': 'page_white_acrobat.png' | ||
228 | + , 'default': 'page_white.png' | ||
229 | +}; |
1 | +/*! | ||
2 | + * Connect - errorHandler | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var utils = require('../utils') | ||
13 | + , fs = require('fs'); | ||
14 | + | ||
15 | +// environment | ||
16 | + | ||
17 | +var env = process.env.NODE_ENV || 'development'; | ||
18 | + | ||
19 | +/** | ||
20 | + * Error handler: | ||
21 | + * | ||
22 | + * Development error handler, providing stack traces | ||
23 | + * and error message responses for requests accepting text, html, | ||
24 | + * or json. | ||
25 | + * | ||
26 | + * Text: | ||
27 | + * | ||
28 | + * By default, and when _text/plain_ is accepted a simple stack trace | ||
29 | + * or error message will be returned. | ||
30 | + * | ||
31 | + * JSON: | ||
32 | + * | ||
33 | + * When _application/json_ is accepted, connect will respond with | ||
34 | + * an object in the form of `{ "error": error }`. | ||
35 | + * | ||
36 | + * HTML: | ||
37 | + * | ||
38 | + * When accepted connect will output a nice html stack trace. | ||
39 | + * | ||
40 | + * @return {Function} | ||
41 | + * @api public | ||
42 | + */ | ||
43 | + | ||
44 | +exports = module.exports = function errorHandler(){ | ||
45 | + return function errorHandler(err, req, res, next){ | ||
46 | + if (err.status) res.statusCode = err.status; | ||
47 | + if (res.statusCode < 400) res.statusCode = 500; | ||
48 | + if ('test' != env) console.error(err.stack); | ||
49 | + var accept = req.headers.accept || ''; | ||
50 | + // html | ||
51 | + if (~accept.indexOf('html')) { | ||
52 | + fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){ | ||
53 | + fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){ | ||
54 | + var stack = (err.stack || '') | ||
55 | + .split('\n').slice(1) | ||
56 | + .map(function(v){ return '<li>' + v + '</li>'; }).join(''); | ||
57 | + html = html | ||
58 | + .replace('{style}', style) | ||
59 | + .replace('{stack}', stack) | ||
60 | + .replace('{title}', exports.title) | ||
61 | + .replace('{statusCode}', res.statusCode) | ||
62 | + .replace(/\{error\}/g, utils.escape(err.toString())); | ||
63 | + res.setHeader('Content-Type', 'text/html; charset=utf-8'); | ||
64 | + res.end(html); | ||
65 | + }); | ||
66 | + }); | ||
67 | + // json | ||
68 | + } else if (~accept.indexOf('json')) { | ||
69 | + var error = { message: err.message, stack: err.stack }; | ||
70 | + for (var prop in err) error[prop] = err[prop]; | ||
71 | + var json = JSON.stringify({ error: error }); | ||
72 | + res.setHeader('Content-Type', 'application/json'); | ||
73 | + res.end(json); | ||
74 | + // plain text | ||
75 | + } else { | ||
76 | + res.writeHead(res.statusCode, { 'Content-Type': 'text/plain' }); | ||
77 | + res.end(err.stack); | ||
78 | + } | ||
79 | + }; | ||
80 | +}; | ||
81 | + | ||
82 | +/** | ||
83 | + * Template title, framework authors may override this value. | ||
84 | + */ | ||
85 | + | ||
86 | +exports.title = 'Connect'; |
1 | +/*! | ||
2 | + * Connect - favicon | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var fs = require('fs') | ||
13 | + , utils = require('../utils'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Favicon: | ||
17 | + * | ||
18 | + * By default serves the connect favicon, or the favicon | ||
19 | + * located by the given `path`. | ||
20 | + * | ||
21 | + * Options: | ||
22 | + * | ||
23 | + * - `maxAge` cache-control max-age directive, defaulting to 1 day | ||
24 | + * | ||
25 | + * Examples: | ||
26 | + * | ||
27 | + * Serve default favicon: | ||
28 | + * | ||
29 | + * connect() | ||
30 | + * .use(connect.favicon()) | ||
31 | + * | ||
32 | + * Serve favicon before logging for brevity: | ||
33 | + * | ||
34 | + * connect() | ||
35 | + * .use(connect.favicon()) | ||
36 | + * .use(connect.logger('dev')) | ||
37 | + * | ||
38 | + * Serve custom favicon: | ||
39 | + * | ||
40 | + * connect() | ||
41 | + * .use(connect.favicon('public/favicon.ico')) | ||
42 | + * | ||
43 | + * @param {String} path | ||
44 | + * @param {Object} options | ||
45 | + * @return {Function} | ||
46 | + * @api public | ||
47 | + */ | ||
48 | + | ||
49 | +module.exports = function favicon(path, options){ | ||
50 | + var options = options || {} | ||
51 | + , path = path || __dirname + '/../public/favicon.ico' | ||
52 | + , maxAge = options.maxAge || 86400000 | ||
53 | + , icon; // favicon cache | ||
54 | + | ||
55 | + return function favicon(req, res, next){ | ||
56 | + if ('/favicon.ico' == req.url) { | ||
57 | + if (icon) { | ||
58 | + res.writeHead(200, icon.headers); | ||
59 | + res.end(icon.body); | ||
60 | + } else { | ||
61 | + fs.readFile(path, function(err, buf){ | ||
62 | + if (err) return next(err); | ||
63 | + icon = { | ||
64 | + headers: { | ||
65 | + 'Content-Type': 'image/x-icon' | ||
66 | + , 'Content-Length': buf.length | ||
67 | + , 'ETag': '"' + utils.md5(buf) + '"' | ||
68 | + , 'Cache-Control': 'public, max-age=' + (maxAge / 1000) | ||
69 | + }, | ||
70 | + body: buf | ||
71 | + }; | ||
72 | + res.writeHead(200, icon.headers); | ||
73 | + res.end(icon.body); | ||
74 | + }); | ||
75 | + } | ||
76 | + } else { | ||
77 | + next(); | ||
78 | + } | ||
79 | + }; | ||
80 | +}; |
node_modules/connect/lib/middleware/json.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect - json | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('../utils') | ||
14 | + , _limit = require('./limit'); | ||
15 | + | ||
16 | +/** | ||
17 | + * noop middleware. | ||
18 | + */ | ||
19 | + | ||
20 | +function noop(req, res, next) { | ||
21 | + next(); | ||
22 | +} | ||
23 | + | ||
24 | +/** | ||
25 | + * JSON: | ||
26 | + * | ||
27 | + * Parse JSON request bodies, providing the | ||
28 | + * parsed object as `req.body`. | ||
29 | + * | ||
30 | + * Options: | ||
31 | + * | ||
32 | + * - `strict` when `false` anything `JSON.parse()` accepts will be parsed | ||
33 | + * - `reviver` used as the second "reviver" argument for JSON.parse | ||
34 | + * - `limit` byte limit disabled by default | ||
35 | + * | ||
36 | + * @param {Object} options | ||
37 | + * @return {Function} | ||
38 | + * @api public | ||
39 | + */ | ||
40 | + | ||
41 | +exports = module.exports = function(options){ | ||
42 | + var options = options || {} | ||
43 | + , strict = options.strict !== false; | ||
44 | + | ||
45 | + var limit = options.limit | ||
46 | + ? _limit(options.limit) | ||
47 | + : noop; | ||
48 | + | ||
49 | + return function json(req, res, next) { | ||
50 | + if (req._body) return next(); | ||
51 | + req.body = req.body || {}; | ||
52 | + | ||
53 | + if (!utils.hasBody(req)) return next(); | ||
54 | + | ||
55 | + // check Content-Type | ||
56 | + if (!exports.regexp.test(utils.mime(req))) return next(); | ||
57 | + | ||
58 | + // flag as parsed | ||
59 | + req._body = true; | ||
60 | + | ||
61 | + // parse | ||
62 | + limit(req, res, function(err){ | ||
63 | + if (err) return next(err); | ||
64 | + var buf = ''; | ||
65 | + req.setEncoding('utf8'); | ||
66 | + req.on('data', function(chunk){ buf += chunk }); | ||
67 | + req.on('end', function(){ | ||
68 | + var first = buf.trim()[0]; | ||
69 | + | ||
70 | + if (0 == buf.length) { | ||
71 | + return next(utils.error(400, 'invalid json, empty body')); | ||
72 | + } | ||
73 | + | ||
74 | + if (strict && '{' != first && '[' != first) return next(utils.error(400, 'invalid json')); | ||
75 | + try { | ||
76 | + req.body = JSON.parse(buf, options.reviver); | ||
77 | + } catch (err){ | ||
78 | + err.body = buf; | ||
79 | + err.status = 400; | ||
80 | + return next(err); | ||
81 | + } | ||
82 | + next(); | ||
83 | + }); | ||
84 | + }); | ||
85 | + }; | ||
86 | +}; | ||
87 | + | ||
88 | +exports.regexp = /^application\/([\w!#\$%&\*`\-\.\^~]*\+)?json$/i; | ||
89 | + |
node_modules/connect/lib/middleware/limit.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect - limit | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var utils = require('../utils'), | ||
13 | + brokenPause = utils.brokenPause; | ||
14 | + | ||
15 | +/** | ||
16 | + * Limit: | ||
17 | + * | ||
18 | + * Limit request bodies to the given size in `bytes`. | ||
19 | + * | ||
20 | + * A string representation of the bytesize may also be passed, | ||
21 | + * for example "5mb", "200kb", "1gb", etc. | ||
22 | + * | ||
23 | + * connect() | ||
24 | + * .use(connect.limit('5.5mb')) | ||
25 | + * .use(handleImageUpload) | ||
26 | + * | ||
27 | + * @param {Number|String} bytes | ||
28 | + * @return {Function} | ||
29 | + * @api public | ||
30 | + */ | ||
31 | + | ||
32 | +module.exports = function limit(bytes){ | ||
33 | + if ('string' == typeof bytes) bytes = utils.parseBytes(bytes); | ||
34 | + if ('number' != typeof bytes) throw new Error('limit() bytes required'); | ||
35 | + return function limit(req, res, next){ | ||
36 | + var received = 0 | ||
37 | + , len = req.headers['content-length'] | ||
38 | + ? parseInt(req.headers['content-length'], 10) | ||
39 | + : null; | ||
40 | + | ||
41 | + // self-awareness | ||
42 | + if (req._limit) return next(); | ||
43 | + req._limit = true; | ||
44 | + | ||
45 | + // limit by content-length | ||
46 | + if (len && len > bytes) return next(utils.error(413)); | ||
47 | + | ||
48 | + // limit | ||
49 | + if (brokenPause) { | ||
50 | + listen(); | ||
51 | + } else { | ||
52 | + req.on('newListener', function handler(event) { | ||
53 | + if (event !== 'data') return; | ||
54 | + | ||
55 | + req.removeListener('newListener', handler); | ||
56 | + // Start listening at the end of the current loop | ||
57 | + // otherwise the request will be consumed too early. | ||
58 | + // Sideaffect is `limit` will miss the first chunk, | ||
59 | + // but that's not a big deal. | ||
60 | + // Unfortunately, the tests don't have large enough | ||
61 | + // request bodies to test this. | ||
62 | + process.nextTick(listen); | ||
63 | + }); | ||
64 | + }; | ||
65 | + | ||
66 | + next(); | ||
67 | + | ||
68 | + function listen() { | ||
69 | + req.on('data', function(chunk) { | ||
70 | + received += Buffer.isBuffer(chunk) | ||
71 | + ? chunk.length : | ||
72 | + Buffer.byteLength(chunk); | ||
73 | + | ||
74 | + if (received > bytes) req.destroy(); | ||
75 | + }); | ||
76 | + }; | ||
77 | + }; | ||
78 | +}; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/*! | ||
2 | + * Connect - logger | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var bytes = require('bytes'); | ||
13 | + | ||
14 | +/*! | ||
15 | + * Log buffer. | ||
16 | + */ | ||
17 | + | ||
18 | +var buf = []; | ||
19 | + | ||
20 | +/*! | ||
21 | + * Default log buffer duration. | ||
22 | + */ | ||
23 | + | ||
24 | +var defaultBufferDuration = 1000; | ||
25 | + | ||
26 | +/** | ||
27 | + * Logger: | ||
28 | + * | ||
29 | + * Log requests with the given `options` or a `format` string. | ||
30 | + * | ||
31 | + * Options: | ||
32 | + * | ||
33 | + * - `format` Format string, see below for tokens | ||
34 | + * - `stream` Output stream, defaults to _stdout_ | ||
35 | + * - `buffer` Buffer duration, defaults to 1000ms when _true_ | ||
36 | + * - `immediate` Write log line on request instead of response (for response times) | ||
37 | + * | ||
38 | + * Tokens: | ||
39 | + * | ||
40 | + * - `:req[header]` ex: `:req[Accept]` | ||
41 | + * - `:res[header]` ex: `:res[Content-Length]` | ||
42 | + * - `:http-version` | ||
43 | + * - `:response-time` | ||
44 | + * - `:remote-addr` | ||
45 | + * - `:date` | ||
46 | + * - `:method` | ||
47 | + * - `:url` | ||
48 | + * - `:referrer` | ||
49 | + * - `:user-agent` | ||
50 | + * - `:status` | ||
51 | + * | ||
52 | + * Formats: | ||
53 | + * | ||
54 | + * Pre-defined formats that ship with connect: | ||
55 | + * | ||
56 | + * - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"' | ||
57 | + * - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms' | ||
58 | + * - `tiny` ':method :url :status :res[content-length] - :response-time ms' | ||
59 | + * - `dev` concise output colored by response status for development use | ||
60 | + * | ||
61 | + * Examples: | ||
62 | + * | ||
63 | + * connect.logger() // default | ||
64 | + * connect.logger('short') | ||
65 | + * connect.logger('tiny') | ||
66 | + * connect.logger({ immediate: true, format: 'dev' }) | ||
67 | + * connect.logger(':method :url - :referrer') | ||
68 | + * connect.logger(':req[content-type] -> :res[content-type]') | ||
69 | + * connect.logger(function(tokens, req, res){ return 'some format string' }) | ||
70 | + * | ||
71 | + * Defining Tokens: | ||
72 | + * | ||
73 | + * To define a token, simply invoke `connect.logger.token()` with the | ||
74 | + * name and a callback function. The value returned is then available | ||
75 | + * as ":type" in this case. | ||
76 | + * | ||
77 | + * connect.logger.token('type', function(req, res){ return req.headers['content-type']; }) | ||
78 | + * | ||
79 | + * Defining Formats: | ||
80 | + * | ||
81 | + * All default formats are defined this way, however it's public API as well: | ||
82 | + * | ||
83 | + * connect.logger.format('name', 'string or function') | ||
84 | + * | ||
85 | + * @param {String|Function|Object} format or options | ||
86 | + * @return {Function} | ||
87 | + * @api public | ||
88 | + */ | ||
89 | + | ||
90 | +exports = module.exports = function logger(options) { | ||
91 | + if ('object' == typeof options) { | ||
92 | + options = options || {}; | ||
93 | + } else if (options) { | ||
94 | + options = { format: options }; | ||
95 | + } else { | ||
96 | + options = {}; | ||
97 | + } | ||
98 | + | ||
99 | + // output on request instead of response | ||
100 | + var immediate = options.immediate; | ||
101 | + | ||
102 | + // format name | ||
103 | + var fmt = exports[options.format] || options.format || exports.default; | ||
104 | + | ||
105 | + // compile format | ||
106 | + if ('function' != typeof fmt) fmt = compile(fmt); | ||
107 | + | ||
108 | + // options | ||
109 | + var stream = options.stream || process.stdout | ||
110 | + , buffer = options.buffer; | ||
111 | + | ||
112 | + // buffering support | ||
113 | + if (buffer) { | ||
114 | + var realStream = stream | ||
115 | + , interval = 'number' == typeof buffer | ||
116 | + ? buffer | ||
117 | + : defaultBufferDuration; | ||
118 | + | ||
119 | + // flush interval | ||
120 | + setInterval(function(){ | ||
121 | + if (buf.length) { | ||
122 | + realStream.write(buf.join('')); | ||
123 | + buf.length = 0; | ||
124 | + } | ||
125 | + }, interval); | ||
126 | + | ||
127 | + // swap the stream | ||
128 | + stream = { | ||
129 | + write: function(str){ | ||
130 | + buf.push(str); | ||
131 | + } | ||
132 | + }; | ||
133 | + } | ||
134 | + | ||
135 | + return function logger(req, res, next) { | ||
136 | + req._startTime = new Date; | ||
137 | + | ||
138 | + // immediate | ||
139 | + if (immediate) { | ||
140 | + var line = fmt(exports, req, res); | ||
141 | + if (null == line) return; | ||
142 | + stream.write(line + '\n'); | ||
143 | + // proxy end to output logging | ||
144 | + } else { | ||
145 | + var end = res.end; | ||
146 | + res.end = function(chunk, encoding){ | ||
147 | + res.end = end; | ||
148 | + res.end(chunk, encoding); | ||
149 | + var line = fmt(exports, req, res); | ||
150 | + if (null == line) return; | ||
151 | + stream.write(line + '\n'); | ||
152 | + }; | ||
153 | + } | ||
154 | + | ||
155 | + | ||
156 | + next(); | ||
157 | + }; | ||
158 | +}; | ||
159 | + | ||
160 | +/** | ||
161 | + * Compile `fmt` into a function. | ||
162 | + * | ||
163 | + * @param {String} fmt | ||
164 | + * @return {Function} | ||
165 | + * @api private | ||
166 | + */ | ||
167 | + | ||
168 | +function compile(fmt) { | ||
169 | + fmt = fmt.replace(/"/g, '\\"'); | ||
170 | + var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){ | ||
171 | + return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "'; | ||
172 | + }) + '";' | ||
173 | + return new Function('tokens, req, res', js); | ||
174 | +}; | ||
175 | + | ||
176 | +/** | ||
177 | + * Define a token function with the given `name`, | ||
178 | + * and callback `fn(req, res)`. | ||
179 | + * | ||
180 | + * @param {String} name | ||
181 | + * @param {Function} fn | ||
182 | + * @return {Object} exports for chaining | ||
183 | + * @api public | ||
184 | + */ | ||
185 | + | ||
186 | +exports.token = function(name, fn) { | ||
187 | + exports[name] = fn; | ||
188 | + return this; | ||
189 | +}; | ||
190 | + | ||
191 | +/** | ||
192 | + * Define a `fmt` with the given `name`. | ||
193 | + * | ||
194 | + * @param {String} name | ||
195 | + * @param {String|Function} fmt | ||
196 | + * @return {Object} exports for chaining | ||
197 | + * @api public | ||
198 | + */ | ||
199 | + | ||
200 | +exports.format = function(name, str){ | ||
201 | + exports[name] = str; | ||
202 | + return this; | ||
203 | +}; | ||
204 | + | ||
205 | +/** | ||
206 | + * Default format. | ||
207 | + */ | ||
208 | + | ||
209 | +exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'); | ||
210 | + | ||
211 | +/** | ||
212 | + * Short format. | ||
213 | + */ | ||
214 | + | ||
215 | +exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'); | ||
216 | + | ||
217 | +/** | ||
218 | + * Tiny format. | ||
219 | + */ | ||
220 | + | ||
221 | +exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms'); | ||
222 | + | ||
223 | +/** | ||
224 | + * dev (colored) | ||
225 | + */ | ||
226 | + | ||
227 | +exports.format('dev', function(tokens, req, res){ | ||
228 | + var status = res.statusCode | ||
229 | + , len = parseInt(res.getHeader('Content-Length'), 10) | ||
230 | + , color = 32; | ||
231 | + | ||
232 | + if (status >= 500) color = 31 | ||
233 | + else if (status >= 400) color = 33 | ||
234 | + else if (status >= 300) color = 36; | ||
235 | + | ||
236 | + len = isNaN(len) | ||
237 | + ? '' | ||
238 | + : len = ' - ' + bytes(len); | ||
239 | + | ||
240 | + return '\x1b[90m' + req.method | ||
241 | + + ' ' + req.originalUrl + ' ' | ||
242 | + + '\x1b[' + color + 'm' + res.statusCode | ||
243 | + + ' \x1b[90m' | ||
244 | + + (new Date - req._startTime) | ||
245 | + + 'ms' + len | ||
246 | + + '\x1b[0m'; | ||
247 | +}); | ||
248 | + | ||
249 | +/** | ||
250 | + * request url | ||
251 | + */ | ||
252 | + | ||
253 | +exports.token('url', function(req){ | ||
254 | + return req.originalUrl || req.url; | ||
255 | +}); | ||
256 | + | ||
257 | +/** | ||
258 | + * request method | ||
259 | + */ | ||
260 | + | ||
261 | +exports.token('method', function(req){ | ||
262 | + return req.method; | ||
263 | +}); | ||
264 | + | ||
265 | +/** | ||
266 | + * response time in milliseconds | ||
267 | + */ | ||
268 | + | ||
269 | +exports.token('response-time', function(req){ | ||
270 | + return new Date - req._startTime; | ||
271 | +}); | ||
272 | + | ||
273 | +/** | ||
274 | + * UTC date | ||
275 | + */ | ||
276 | + | ||
277 | +exports.token('date', function(){ | ||
278 | + return new Date().toUTCString(); | ||
279 | +}); | ||
280 | + | ||
281 | +/** | ||
282 | + * response status code | ||
283 | + */ | ||
284 | + | ||
285 | +exports.token('status', function(req, res){ | ||
286 | + return res.statusCode; | ||
287 | +}); | ||
288 | + | ||
289 | +/** | ||
290 | + * normalized referrer | ||
291 | + */ | ||
292 | + | ||
293 | +exports.token('referrer', function(req){ | ||
294 | + return req.headers['referer'] || req.headers['referrer']; | ||
295 | +}); | ||
296 | + | ||
297 | +/** | ||
298 | + * remote address | ||
299 | + */ | ||
300 | + | ||
301 | +exports.token('remote-addr', function(req){ | ||
302 | + if (req.ip) return req.ip; | ||
303 | + var sock = req.socket; | ||
304 | + if (sock.socket) return sock.socket.remoteAddress; | ||
305 | + return sock.remoteAddress; | ||
306 | +}); | ||
307 | + | ||
308 | +/** | ||
309 | + * HTTP version | ||
310 | + */ | ||
311 | + | ||
312 | +exports.token('http-version', function(req){ | ||
313 | + return req.httpVersionMajor + '.' + req.httpVersionMinor; | ||
314 | +}); | ||
315 | + | ||
316 | +/** | ||
317 | + * UA string | ||
318 | + */ | ||
319 | + | ||
320 | +exports.token('user-agent', function(req){ | ||
321 | + return req.headers['user-agent']; | ||
322 | +}); | ||
323 | + | ||
324 | +/** | ||
325 | + * request header | ||
326 | + */ | ||
327 | + | ||
328 | +exports.token('req', function(req, res, field){ | ||
329 | + return req.headers[field.toLowerCase()]; | ||
330 | +}); | ||
331 | + | ||
332 | +/** | ||
333 | + * response header | ||
334 | + */ | ||
335 | + | ||
336 | +exports.token('res', function(req, res, field){ | ||
337 | + return (res._headers || {})[field.toLowerCase()]; | ||
338 | +}); | ||
339 | + |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - methodOverride | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var methods = require('methods'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Method Override: | ||
17 | + * | ||
18 | + * Provides faux HTTP method support. | ||
19 | + * | ||
20 | + * Pass an optional `key` to use when checking for | ||
21 | + * a method override, othewise defaults to _\_method_. | ||
22 | + * The original method is available via `req.originalMethod`. | ||
23 | + * | ||
24 | + * @param {String} key | ||
25 | + * @return {Function} | ||
26 | + * @api public | ||
27 | + */ | ||
28 | + | ||
29 | +module.exports = function methodOverride(key){ | ||
30 | + key = key || "_method"; | ||
31 | + return function methodOverride(req, res, next) { | ||
32 | + var method; | ||
33 | + req.originalMethod = req.originalMethod || req.method; | ||
34 | + | ||
35 | + // req.body | ||
36 | + if (req.body && key in req.body) { | ||
37 | + method = req.body[key].toLowerCase(); | ||
38 | + delete req.body[key]; | ||
39 | + } | ||
40 | + | ||
41 | + // check X-HTTP-Method-Override | ||
42 | + if (req.headers['x-http-method-override']) { | ||
43 | + method = req.headers['x-http-method-override'].toLowerCase(); | ||
44 | + } | ||
45 | + | ||
46 | + // replace | ||
47 | + if (supports(method)) req.method = method.toUpperCase(); | ||
48 | + | ||
49 | + next(); | ||
50 | + }; | ||
51 | +}; | ||
52 | + | ||
53 | +/** | ||
54 | + * Check if node supports `method`. | ||
55 | + */ | ||
56 | + | ||
57 | +function supports(method) { | ||
58 | + return ~methods.indexOf(method); | ||
59 | +} |
1 | +/*! | ||
2 | + * Connect - multipart | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var formidable = require('formidable') | ||
13 | + , _limit = require('./limit') | ||
14 | + , utils = require('../utils') | ||
15 | + , qs = require('qs'); | ||
16 | + | ||
17 | +/** | ||
18 | + * noop middleware. | ||
19 | + */ | ||
20 | + | ||
21 | +function noop(req, res, next) { | ||
22 | + next(); | ||
23 | +} | ||
24 | + | ||
25 | +/** | ||
26 | + * Multipart: | ||
27 | + * | ||
28 | + * Parse multipart/form-data request bodies, | ||
29 | + * providing the parsed object as `req.body` | ||
30 | + * and `req.files`. | ||
31 | + * | ||
32 | + * Configuration: | ||
33 | + * | ||
34 | + * The options passed are merged with [formidable](https://github.com/felixge/node-formidable)'s | ||
35 | + * `IncomingForm` object, allowing you to configure the upload directory, | ||
36 | + * size limits, etc. For example if you wish to change the upload dir do the following. | ||
37 | + * | ||
38 | + * app.use(connect.multipart({ uploadDir: path })); | ||
39 | + * | ||
40 | + * Options: | ||
41 | + * | ||
42 | + * - `limit` byte limit defaulting to none | ||
43 | + * - `defer` defers processing and exposes the Formidable form object as `req.form`. | ||
44 | + * `next()` is called without waiting for the form's "end" event. | ||
45 | + * This option is useful if you need to bind to the "progress" event, for example. | ||
46 | + * | ||
47 | + * @param {Object} options | ||
48 | + * @return {Function} | ||
49 | + * @api public | ||
50 | + */ | ||
51 | + | ||
52 | +exports = module.exports = function(options){ | ||
53 | + options = options || {}; | ||
54 | + | ||
55 | + var limit = options.limit | ||
56 | + ? _limit(options.limit) | ||
57 | + : noop; | ||
58 | + | ||
59 | + return function multipart(req, res, next) { | ||
60 | + if (req._body) return next(); | ||
61 | + req.body = req.body || {}; | ||
62 | + req.files = req.files || {}; | ||
63 | + | ||
64 | + if (!utils.hasBody(req)) return next(); | ||
65 | + | ||
66 | + // ignore GET | ||
67 | + if ('GET' == req.method || 'HEAD' == req.method) return next(); | ||
68 | + | ||
69 | + // check Content-Type | ||
70 | + if ('multipart/form-data' != utils.mime(req)) return next(); | ||
71 | + | ||
72 | + // flag as parsed | ||
73 | + req._body = true; | ||
74 | + | ||
75 | + // parse | ||
76 | + limit(req, res, function(err){ | ||
77 | + if (err) return next(err); | ||
78 | + | ||
79 | + var form = new formidable.IncomingForm | ||
80 | + , data = {} | ||
81 | + , files = {} | ||
82 | + , done; | ||
83 | + | ||
84 | + Object.keys(options).forEach(function(key){ | ||
85 | + form[key] = options[key]; | ||
86 | + }); | ||
87 | + | ||
88 | + function ondata(name, val, data){ | ||
89 | + if (Array.isArray(data[name])) { | ||
90 | + data[name].push(val); | ||
91 | + } else if (data[name]) { | ||
92 | + data[name] = [data[name], val]; | ||
93 | + } else { | ||
94 | + data[name] = val; | ||
95 | + } | ||
96 | + } | ||
97 | + | ||
98 | + form.on('field', function(name, val){ | ||
99 | + ondata(name, val, data); | ||
100 | + }); | ||
101 | + | ||
102 | + form.on('file', function(name, val){ | ||
103 | + ondata(name, val, files); | ||
104 | + }); | ||
105 | + | ||
106 | + form.on('error', function(err){ | ||
107 | + if (!options.defer) { | ||
108 | + err.status = 400; | ||
109 | + next(err); | ||
110 | + } | ||
111 | + done = true; | ||
112 | + }); | ||
113 | + | ||
114 | + form.on('end', function(){ | ||
115 | + if (done) return; | ||
116 | + try { | ||
117 | + req.body = qs.parse(data); | ||
118 | + req.files = qs.parse(files); | ||
119 | + } catch (err) { | ||
120 | + form.emit('error', err); | ||
121 | + return; | ||
122 | + } | ||
123 | + if (!options.defer) next(); | ||
124 | + }); | ||
125 | + | ||
126 | + form.parse(req); | ||
127 | + | ||
128 | + if (options.defer) { | ||
129 | + req.form = form; | ||
130 | + next(); | ||
131 | + } | ||
132 | + }); | ||
133 | + } | ||
134 | +}; |
node_modules/connect/lib/middleware/query.js
0 → 100644
1 | +/*! | ||
2 | + * Connect - query | ||
3 | + * Copyright(c) 2011 TJ Holowaychuk | ||
4 | + * Copyright(c) 2011 Sencha Inc. | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var qs = require('qs') | ||
13 | + , parse = require('../utils').parseUrl; | ||
14 | + | ||
15 | +/** | ||
16 | + * Query: | ||
17 | + * | ||
18 | + * Automatically parse the query-string when available, | ||
19 | + * populating the `req.query` object. | ||
20 | + * | ||
21 | + * Examples: | ||
22 | + * | ||
23 | + * connect() | ||
24 | + * .use(connect.query()) | ||
25 | + * .use(function(req, res){ | ||
26 | + * res.end(JSON.stringify(req.query)); | ||
27 | + * }); | ||
28 | + * | ||
29 | + * The `options` passed are provided to qs.parse function. | ||
30 | + * | ||
31 | + * @param {Object} options | ||
32 | + * @return {Function} | ||
33 | + * @api public | ||
34 | + */ | ||
35 | + | ||
36 | +module.exports = function query(options){ | ||
37 | + return function query(req, res, next){ | ||
38 | + if (!req.query) { | ||
39 | + req.query = ~req.url.indexOf('?') | ||
40 | + ? qs.parse(parse(req).query, options) | ||
41 | + : {}; | ||
42 | + } | ||
43 | + | ||
44 | + next(); | ||
45 | + }; | ||
46 | +}; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - responseTime | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Reponse time: | ||
10 | + * | ||
11 | + * Adds the `X-Response-Time` header displaying the response | ||
12 | + * duration in milliseconds. | ||
13 | + * | ||
14 | + * @return {Function} | ||
15 | + * @api public | ||
16 | + */ | ||
17 | + | ||
18 | +module.exports = function responseTime(){ | ||
19 | + return function(req, res, next){ | ||
20 | + var start = new Date; | ||
21 | + | ||
22 | + if (res._responseTime) return next(); | ||
23 | + res._responseTime = true; | ||
24 | + | ||
25 | + res.on('header', function(){ | ||
26 | + var duration = new Date - start; | ||
27 | + res.setHeader('X-Response-Time', duration + 'ms'); | ||
28 | + }); | ||
29 | + | ||
30 | + next(); | ||
31 | + }; | ||
32 | +}; |
This diff is collapsed. Click to expand it.
1 | + | ||
2 | +/*! | ||
3 | + * Connect - session - Cookie | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('../../utils') | ||
14 | + , cookie = require('cookie'); | ||
15 | + | ||
16 | +/** | ||
17 | + * Initialize a new `Cookie` with the given `options`. | ||
18 | + * | ||
19 | + * @param {IncomingMessage} req | ||
20 | + * @param {Object} options | ||
21 | + * @api private | ||
22 | + */ | ||
23 | + | ||
24 | +var Cookie = module.exports = function Cookie(options) { | ||
25 | + this.path = '/'; | ||
26 | + this.maxAge = null; | ||
27 | + this.httpOnly = true; | ||
28 | + if (options) utils.merge(this, options); | ||
29 | + this.originalMaxAge = undefined == this.originalMaxAge | ||
30 | + ? this.maxAge | ||
31 | + : this.originalMaxAge; | ||
32 | +}; | ||
33 | + | ||
34 | +/*! | ||
35 | + * Prototype. | ||
36 | + */ | ||
37 | + | ||
38 | +Cookie.prototype = { | ||
39 | + | ||
40 | + /** | ||
41 | + * Set expires `date`. | ||
42 | + * | ||
43 | + * @param {Date} date | ||
44 | + * @api public | ||
45 | + */ | ||
46 | + | ||
47 | + set expires(date) { | ||
48 | + this._expires = date; | ||
49 | + this.originalMaxAge = this.maxAge; | ||
50 | + }, | ||
51 | + | ||
52 | + /** | ||
53 | + * Get expires `date`. | ||
54 | + * | ||
55 | + * @return {Date} | ||
56 | + * @api public | ||
57 | + */ | ||
58 | + | ||
59 | + get expires() { | ||
60 | + return this._expires; | ||
61 | + }, | ||
62 | + | ||
63 | + /** | ||
64 | + * Set expires via max-age in `ms`. | ||
65 | + * | ||
66 | + * @param {Number} ms | ||
67 | + * @api public | ||
68 | + */ | ||
69 | + | ||
70 | + set maxAge(ms) { | ||
71 | + this.expires = 'number' == typeof ms | ||
72 | + ? new Date(Date.now() + ms) | ||
73 | + : ms; | ||
74 | + }, | ||
75 | + | ||
76 | + /** | ||
77 | + * Get expires max-age in `ms`. | ||
78 | + * | ||
79 | + * @return {Number} | ||
80 | + * @api public | ||
81 | + */ | ||
82 | + | ||
83 | + get maxAge() { | ||
84 | + return this.expires instanceof Date | ||
85 | + ? this.expires.valueOf() - Date.now() | ||
86 | + : this.expires; | ||
87 | + }, | ||
88 | + | ||
89 | + /** | ||
90 | + * Return cookie data object. | ||
91 | + * | ||
92 | + * @return {Object} | ||
93 | + * @api private | ||
94 | + */ | ||
95 | + | ||
96 | + get data() { | ||
97 | + return { | ||
98 | + originalMaxAge: this.originalMaxAge | ||
99 | + , expires: this._expires | ||
100 | + , secure: this.secure | ||
101 | + , httpOnly: this.httpOnly | ||
102 | + , domain: this.domain | ||
103 | + , path: this.path | ||
104 | + } | ||
105 | + }, | ||
106 | + | ||
107 | + /** | ||
108 | + * Check if the cookie has a reasonably large max-age. | ||
109 | + * | ||
110 | + * @return {Boolean} | ||
111 | + * @api private | ||
112 | + */ | ||
113 | + | ||
114 | + get hasLongExpires() { | ||
115 | + var week = 604800000; | ||
116 | + return this.maxAge > (4 * week); | ||
117 | + }, | ||
118 | + | ||
119 | + /** | ||
120 | + * Return a serialized cookie string. | ||
121 | + * | ||
122 | + * @return {String} | ||
123 | + * @api public | ||
124 | + */ | ||
125 | + | ||
126 | + serialize: function(name, val){ | ||
127 | + return cookie.serialize(name, val, this.data); | ||
128 | + }, | ||
129 | + | ||
130 | + /** | ||
131 | + * Return JSON representation of this cookie. | ||
132 | + * | ||
133 | + * @return {Object} | ||
134 | + * @api private | ||
135 | + */ | ||
136 | + | ||
137 | + toJSON: function(){ | ||
138 | + return this.data; | ||
139 | + } | ||
140 | +}; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - session - MemoryStore | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var Store = require('./store'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Initialize a new `MemoryStore`. | ||
17 | + * | ||
18 | + * @api public | ||
19 | + */ | ||
20 | + | ||
21 | +var MemoryStore = module.exports = function MemoryStore() { | ||
22 | + this.sessions = {}; | ||
23 | +}; | ||
24 | + | ||
25 | +/** | ||
26 | + * Inherit from `Store.prototype`. | ||
27 | + */ | ||
28 | + | ||
29 | +MemoryStore.prototype.__proto__ = Store.prototype; | ||
30 | + | ||
31 | +/** | ||
32 | + * Attempt to fetch session by the given `sid`. | ||
33 | + * | ||
34 | + * @param {String} sid | ||
35 | + * @param {Function} fn | ||
36 | + * @api public | ||
37 | + */ | ||
38 | + | ||
39 | +MemoryStore.prototype.get = function(sid, fn){ | ||
40 | + var self = this; | ||
41 | + process.nextTick(function(){ | ||
42 | + var expires | ||
43 | + , sess = self.sessions[sid]; | ||
44 | + if (sess) { | ||
45 | + sess = JSON.parse(sess); | ||
46 | + expires = 'string' == typeof sess.cookie.expires | ||
47 | + ? new Date(sess.cookie.expires) | ||
48 | + : sess.cookie.expires; | ||
49 | + if (!expires || new Date < expires) { | ||
50 | + fn(null, sess); | ||
51 | + } else { | ||
52 | + self.destroy(sid, fn); | ||
53 | + } | ||
54 | + } else { | ||
55 | + fn(); | ||
56 | + } | ||
57 | + }); | ||
58 | +}; | ||
59 | + | ||
60 | +/** | ||
61 | + * Commit the given `sess` object associated with the given `sid`. | ||
62 | + * | ||
63 | + * @param {String} sid | ||
64 | + * @param {Session} sess | ||
65 | + * @param {Function} fn | ||
66 | + * @api public | ||
67 | + */ | ||
68 | + | ||
69 | +MemoryStore.prototype.set = function(sid, sess, fn){ | ||
70 | + var self = this; | ||
71 | + process.nextTick(function(){ | ||
72 | + self.sessions[sid] = JSON.stringify(sess); | ||
73 | + fn && fn(); | ||
74 | + }); | ||
75 | +}; | ||
76 | + | ||
77 | +/** | ||
78 | + * Destroy the session associated with the given `sid`. | ||
79 | + * | ||
80 | + * @param {String} sid | ||
81 | + * @api public | ||
82 | + */ | ||
83 | + | ||
84 | +MemoryStore.prototype.destroy = function(sid, fn){ | ||
85 | + var self = this; | ||
86 | + process.nextTick(function(){ | ||
87 | + delete self.sessions[sid]; | ||
88 | + fn && fn(); | ||
89 | + }); | ||
90 | +}; | ||
91 | + | ||
92 | +/** | ||
93 | + * Invoke the given callback `fn` with all active sessions. | ||
94 | + * | ||
95 | + * @param {Function} fn | ||
96 | + * @api public | ||
97 | + */ | ||
98 | + | ||
99 | +MemoryStore.prototype.all = function(fn){ | ||
100 | + var arr = [] | ||
101 | + , keys = Object.keys(this.sessions); | ||
102 | + for (var i = 0, len = keys.length; i < len; ++i) { | ||
103 | + arr.push(this.sessions[keys[i]]); | ||
104 | + } | ||
105 | + fn(null, arr); | ||
106 | +}; | ||
107 | + | ||
108 | +/** | ||
109 | + * Clear all sessions. | ||
110 | + * | ||
111 | + * @param {Function} fn | ||
112 | + * @api public | ||
113 | + */ | ||
114 | + | ||
115 | +MemoryStore.prototype.clear = function(fn){ | ||
116 | + this.sessions = {}; | ||
117 | + fn && fn(); | ||
118 | +}; | ||
119 | + | ||
120 | +/** | ||
121 | + * Fetch number of sessions. | ||
122 | + * | ||
123 | + * @param {Function} fn | ||
124 | + * @api public | ||
125 | + */ | ||
126 | + | ||
127 | +MemoryStore.prototype.length = function(fn){ | ||
128 | + fn(null, Object.keys(this.sessions).length); | ||
129 | +}; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - session - Session | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('../../utils'); | ||
14 | + | ||
15 | +/** | ||
16 | + * Create a new `Session` with the given request and `data`. | ||
17 | + * | ||
18 | + * @param {IncomingRequest} req | ||
19 | + * @param {Object} data | ||
20 | + * @api private | ||
21 | + */ | ||
22 | + | ||
23 | +var Session = module.exports = function Session(req, data) { | ||
24 | + Object.defineProperty(this, 'req', { value: req }); | ||
25 | + Object.defineProperty(this, 'id', { value: req.sessionID }); | ||
26 | + if ('object' == typeof data) utils.merge(this, data); | ||
27 | +}; | ||
28 | + | ||
29 | +/** | ||
30 | + * Update reset `.cookie.maxAge` to prevent | ||
31 | + * the cookie from expiring when the | ||
32 | + * session is still active. | ||
33 | + * | ||
34 | + * @return {Session} for chaining | ||
35 | + * @api public | ||
36 | + */ | ||
37 | + | ||
38 | +Session.prototype.touch = function(){ | ||
39 | + return this.resetMaxAge(); | ||
40 | +}; | ||
41 | + | ||
42 | +/** | ||
43 | + * Reset `.maxAge` to `.originalMaxAge`. | ||
44 | + * | ||
45 | + * @return {Session} for chaining | ||
46 | + * @api public | ||
47 | + */ | ||
48 | + | ||
49 | +Session.prototype.resetMaxAge = function(){ | ||
50 | + this.cookie.maxAge = this.cookie.originalMaxAge; | ||
51 | + return this; | ||
52 | +}; | ||
53 | + | ||
54 | +/** | ||
55 | + * Save the session data with optional callback `fn(err)`. | ||
56 | + * | ||
57 | + * @param {Function} fn | ||
58 | + * @return {Session} for chaining | ||
59 | + * @api public | ||
60 | + */ | ||
61 | + | ||
62 | +Session.prototype.save = function(fn){ | ||
63 | + this.req.sessionStore.set(this.id, this, fn || function(){}); | ||
64 | + return this; | ||
65 | +}; | ||
66 | + | ||
67 | +/** | ||
68 | + * Re-loads the session data _without_ altering | ||
69 | + * the maxAge properties. Invokes the callback `fn(err)`, | ||
70 | + * after which time if no exception has occurred the | ||
71 | + * `req.session` property will be a new `Session` object, | ||
72 | + * although representing the same session. | ||
73 | + * | ||
74 | + * @param {Function} fn | ||
75 | + * @return {Session} for chaining | ||
76 | + * @api public | ||
77 | + */ | ||
78 | + | ||
79 | +Session.prototype.reload = function(fn){ | ||
80 | + var req = this.req | ||
81 | + , store = this.req.sessionStore; | ||
82 | + store.get(this.id, function(err, sess){ | ||
83 | + if (err) return fn(err); | ||
84 | + if (!sess) return fn(new Error('failed to load session')); | ||
85 | + store.createSession(req, sess); | ||
86 | + fn(); | ||
87 | + }); | ||
88 | + return this; | ||
89 | +}; | ||
90 | + | ||
91 | +/** | ||
92 | + * Destroy `this` session. | ||
93 | + * | ||
94 | + * @param {Function} fn | ||
95 | + * @return {Session} for chaining | ||
96 | + * @api public | ||
97 | + */ | ||
98 | + | ||
99 | +Session.prototype.destroy = function(fn){ | ||
100 | + delete this.req.session; | ||
101 | + this.req.sessionStore.destroy(this.id, fn); | ||
102 | + return this; | ||
103 | +}; | ||
104 | + | ||
105 | +/** | ||
106 | + * Regenerate this request's session. | ||
107 | + * | ||
108 | + * @param {Function} fn | ||
109 | + * @return {Session} for chaining | ||
110 | + * @api public | ||
111 | + */ | ||
112 | + | ||
113 | +Session.prototype.regenerate = function(fn){ | ||
114 | + this.req.sessionStore.regenerate(this.req, fn); | ||
115 | + return this; | ||
116 | +}; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - session - Store | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var EventEmitter = require('events').EventEmitter | ||
14 | + , Session = require('./session') | ||
15 | + , Cookie = require('./cookie'); | ||
16 | + | ||
17 | +/** | ||
18 | + * Initialize abstract `Store`. | ||
19 | + * | ||
20 | + * @api private | ||
21 | + */ | ||
22 | + | ||
23 | +var Store = module.exports = function Store(options){}; | ||
24 | + | ||
25 | +/** | ||
26 | + * Inherit from `EventEmitter.prototype`. | ||
27 | + */ | ||
28 | + | ||
29 | +Store.prototype.__proto__ = EventEmitter.prototype; | ||
30 | + | ||
31 | +/** | ||
32 | + * Re-generate the given requests's session. | ||
33 | + * | ||
34 | + * @param {IncomingRequest} req | ||
35 | + * @return {Function} fn | ||
36 | + * @api public | ||
37 | + */ | ||
38 | + | ||
39 | +Store.prototype.regenerate = function(req, fn){ | ||
40 | + var self = this; | ||
41 | + this.destroy(req.sessionID, function(err){ | ||
42 | + self.generate(req); | ||
43 | + fn(err); | ||
44 | + }); | ||
45 | +}; | ||
46 | + | ||
47 | +/** | ||
48 | + * Load a `Session` instance via the given `sid` | ||
49 | + * and invoke the callback `fn(err, sess)`. | ||
50 | + * | ||
51 | + * @param {String} sid | ||
52 | + * @param {Function} fn | ||
53 | + * @api public | ||
54 | + */ | ||
55 | + | ||
56 | +Store.prototype.load = function(sid, fn){ | ||
57 | + var self = this; | ||
58 | + this.get(sid, function(err, sess){ | ||
59 | + if (err) return fn(err); | ||
60 | + if (!sess) return fn(); | ||
61 | + var req = { sessionID: sid, sessionStore: self }; | ||
62 | + sess = self.createSession(req, sess); | ||
63 | + fn(null, sess); | ||
64 | + }); | ||
65 | +}; | ||
66 | + | ||
67 | +/** | ||
68 | + * Create session from JSON `sess` data. | ||
69 | + * | ||
70 | + * @param {IncomingRequest} req | ||
71 | + * @param {Object} sess | ||
72 | + * @return {Session} | ||
73 | + * @api private | ||
74 | + */ | ||
75 | + | ||
76 | +Store.prototype.createSession = function(req, sess){ | ||
77 | + var expires = sess.cookie.expires | ||
78 | + , orig = sess.cookie.originalMaxAge; | ||
79 | + sess.cookie = new Cookie(sess.cookie); | ||
80 | + if ('string' == typeof expires) sess.cookie.expires = new Date(expires); | ||
81 | + sess.cookie.originalMaxAge = orig; | ||
82 | + req.session = new Session(req, sess); | ||
83 | + return req.session; | ||
84 | +}; |
1 | +/*! | ||
2 | + * Connect - static | ||
3 | + * Copyright(c) 2010 Sencha Inc. | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var send = require('send') | ||
13 | + , utils = require('../utils') | ||
14 | + , parse = utils.parseUrl | ||
15 | + , url = require('url'); | ||
16 | + | ||
17 | +/** | ||
18 | + * Static: | ||
19 | + * | ||
20 | + * Static file server with the given `root` path. | ||
21 | + * | ||
22 | + * Examples: | ||
23 | + * | ||
24 | + * var oneDay = 86400000; | ||
25 | + * | ||
26 | + * connect() | ||
27 | + * .use(connect.static(__dirname + '/public')) | ||
28 | + * | ||
29 | + * connect() | ||
30 | + * .use(connect.static(__dirname + '/public', { maxAge: oneDay })) | ||
31 | + * | ||
32 | + * Options: | ||
33 | + * | ||
34 | + * - `maxAge` Browser cache maxAge in milliseconds. defaults to 0 | ||
35 | + * - `hidden` Allow transfer of hidden files. defaults to false | ||
36 | + * - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true | ||
37 | + * - `index` Default file name, defaults to 'index.html' | ||
38 | + * | ||
39 | + * @param {String} root | ||
40 | + * @param {Object} options | ||
41 | + * @return {Function} | ||
42 | + * @api public | ||
43 | + */ | ||
44 | + | ||
45 | +exports = module.exports = function(root, options){ | ||
46 | + options = options || {}; | ||
47 | + | ||
48 | + // root required | ||
49 | + if (!root) throw new Error('static() root path required'); | ||
50 | + | ||
51 | + // default redirect | ||
52 | + var redirect = false !== options.redirect; | ||
53 | + | ||
54 | + return function staticMiddleware(req, res, next) { | ||
55 | + if ('GET' != req.method && 'HEAD' != req.method) return next(); | ||
56 | + var path = parse(req).pathname; | ||
57 | + var pause = utils.pause(req); | ||
58 | + | ||
59 | + function resume() { | ||
60 | + next(); | ||
61 | + pause.resume(); | ||
62 | + } | ||
63 | + | ||
64 | + function directory() { | ||
65 | + if (!redirect) return resume(); | ||
66 | + var pathname = url.parse(req.originalUrl).pathname; | ||
67 | + res.statusCode = 303; | ||
68 | + res.setHeader('Location', pathname + '/'); | ||
69 | + res.end('Redirecting to ' + utils.escape(pathname) + '/'); | ||
70 | + } | ||
71 | + | ||
72 | + function error(err) { | ||
73 | + if (404 == err.status) return resume(); | ||
74 | + next(err); | ||
75 | + } | ||
76 | + | ||
77 | + send(req, path) | ||
78 | + .maxage(options.maxAge || 0) | ||
79 | + .root(root) | ||
80 | + .index(options.index || 'index.html') | ||
81 | + .hidden(options.hidden) | ||
82 | + .on('error', error) | ||
83 | + .on('directory', directory) | ||
84 | + .pipe(res); | ||
85 | + }; | ||
86 | +}; | ||
87 | + | ||
88 | +/** | ||
89 | + * Expose mime module. | ||
90 | + * | ||
91 | + * If you wish to extend the mime table use this | ||
92 | + * reference to the "mime" module in the npm registry. | ||
93 | + */ | ||
94 | + | ||
95 | +exports.mime = send.mime; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - staticCache | ||
4 | + * Copyright(c) 2011 Sencha Inc. | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var utils = require('../utils') | ||
13 | + , Cache = require('../cache') | ||
14 | + , fresh = require('fresh'); | ||
15 | + | ||
16 | +/** | ||
17 | + * Static cache: | ||
18 | + * | ||
19 | + * Enables a memory cache layer on top of | ||
20 | + * the `static()` middleware, serving popular | ||
21 | + * static files. | ||
22 | + * | ||
23 | + * By default a maximum of 128 objects are | ||
24 | + * held in cache, with a max of 256k each, | ||
25 | + * totalling ~32mb. | ||
26 | + * | ||
27 | + * A Least-Recently-Used (LRU) cache algo | ||
28 | + * is implemented through the `Cache` object, | ||
29 | + * simply rotating cache objects as they are | ||
30 | + * hit. This means that increasingly popular | ||
31 | + * objects maintain their positions while | ||
32 | + * others get shoved out of the stack and | ||
33 | + * garbage collected. | ||
34 | + * | ||
35 | + * Benchmarks: | ||
36 | + * | ||
37 | + * static(): 2700 rps | ||
38 | + * node-static: 5300 rps | ||
39 | + * static() + staticCache(): 7500 rps | ||
40 | + * | ||
41 | + * Options: | ||
42 | + * | ||
43 | + * - `maxObjects` max cache objects [128] | ||
44 | + * - `maxLength` max cache object length 256kb | ||
45 | + * | ||
46 | + * @param {Object} options | ||
47 | + * @return {Function} | ||
48 | + * @api public | ||
49 | + */ | ||
50 | + | ||
51 | +module.exports = function staticCache(options){ | ||
52 | + var options = options || {} | ||
53 | + , cache = new Cache(options.maxObjects || 128) | ||
54 | + , maxlen = options.maxLength || 1024 * 256; | ||
55 | + | ||
56 | + console.warn('connect.staticCache() is deprecated and will be removed in 3.0'); | ||
57 | + console.warn('use varnish or similar reverse proxy caches.'); | ||
58 | + | ||
59 | + return function staticCache(req, res, next){ | ||
60 | + var key = cacheKey(req) | ||
61 | + , ranges = req.headers.range | ||
62 | + , hasCookies = req.headers.cookie | ||
63 | + , hit = cache.get(key); | ||
64 | + | ||
65 | + // cache static | ||
66 | + // TODO: change from staticCache() -> cache() | ||
67 | + // and make this work for any request | ||
68 | + req.on('static', function(stream){ | ||
69 | + var headers = res._headers | ||
70 | + , cc = utils.parseCacheControl(headers['cache-control'] || '') | ||
71 | + , contentLength = headers['content-length'] | ||
72 | + , hit; | ||
73 | + | ||
74 | + // dont cache set-cookie responses | ||
75 | + if (headers['set-cookie']) return hasCookies = true; | ||
76 | + | ||
77 | + // dont cache when cookies are present | ||
78 | + if (hasCookies) return; | ||
79 | + | ||
80 | + // ignore larger files | ||
81 | + if (!contentLength || contentLength > maxlen) return; | ||
82 | + | ||
83 | + // don't cache partial files | ||
84 | + if (headers['content-range']) return; | ||
85 | + | ||
86 | + // dont cache items we shouldn't be | ||
87 | + // TODO: real support for must-revalidate / no-cache | ||
88 | + if ( cc['no-cache'] | ||
89 | + || cc['no-store'] | ||
90 | + || cc['private'] | ||
91 | + || cc['must-revalidate']) return; | ||
92 | + | ||
93 | + // if already in cache then validate | ||
94 | + if (hit = cache.get(key)){ | ||
95 | + if (headers.etag == hit[0].etag) { | ||
96 | + hit[0].date = new Date; | ||
97 | + return; | ||
98 | + } else { | ||
99 | + cache.remove(key); | ||
100 | + } | ||
101 | + } | ||
102 | + | ||
103 | + // validation notifiactions don't contain a steam | ||
104 | + if (null == stream) return; | ||
105 | + | ||
106 | + // add the cache object | ||
107 | + var arr = []; | ||
108 | + | ||
109 | + // store the chunks | ||
110 | + stream.on('data', function(chunk){ | ||
111 | + arr.push(chunk); | ||
112 | + }); | ||
113 | + | ||
114 | + // flag it as complete | ||
115 | + stream.on('end', function(){ | ||
116 | + var cacheEntry = cache.add(key); | ||
117 | + delete headers['x-cache']; // Clean up (TODO: others) | ||
118 | + cacheEntry.push(200); | ||
119 | + cacheEntry.push(headers); | ||
120 | + cacheEntry.push.apply(cacheEntry, arr); | ||
121 | + }); | ||
122 | + }); | ||
123 | + | ||
124 | + if (req.method == 'GET' || req.method == 'HEAD') { | ||
125 | + if (ranges) { | ||
126 | + next(); | ||
127 | + } else if (!hasCookies && hit && !mustRevalidate(req, hit)) { | ||
128 | + res.setHeader('X-Cache', 'HIT'); | ||
129 | + respondFromCache(req, res, hit); | ||
130 | + } else { | ||
131 | + res.setHeader('X-Cache', 'MISS'); | ||
132 | + next(); | ||
133 | + } | ||
134 | + } else { | ||
135 | + next(); | ||
136 | + } | ||
137 | + } | ||
138 | +}; | ||
139 | + | ||
140 | +/** | ||
141 | + * Respond with the provided cached value. | ||
142 | + * TODO: Assume 200 code, that's iffy. | ||
143 | + * | ||
144 | + * @param {Object} req | ||
145 | + * @param {Object} res | ||
146 | + * @param {Object} cacheEntry | ||
147 | + * @return {String} | ||
148 | + * @api private | ||
149 | + */ | ||
150 | + | ||
151 | +function respondFromCache(req, res, cacheEntry) { | ||
152 | + var status = cacheEntry[0] | ||
153 | + , headers = utils.merge({}, cacheEntry[1]) | ||
154 | + , content = cacheEntry.slice(2); | ||
155 | + | ||
156 | + headers.age = (new Date - new Date(headers.date)) / 1000 || 0; | ||
157 | + | ||
158 | + switch (req.method) { | ||
159 | + case 'HEAD': | ||
160 | + res.writeHead(status, headers); | ||
161 | + res.end(); | ||
162 | + break; | ||
163 | + case 'GET': | ||
164 | + if (utils.conditionalGET(req) && fresh(req.headers, headers)) { | ||
165 | + headers['content-length'] = 0; | ||
166 | + res.writeHead(304, headers); | ||
167 | + res.end(); | ||
168 | + } else { | ||
169 | + res.writeHead(status, headers); | ||
170 | + | ||
171 | + function write() { | ||
172 | + while (content.length) { | ||
173 | + if (false === res.write(content.shift())) { | ||
174 | + res.once('drain', write); | ||
175 | + return; | ||
176 | + } | ||
177 | + } | ||
178 | + res.end(); | ||
179 | + } | ||
180 | + | ||
181 | + write(); | ||
182 | + } | ||
183 | + break; | ||
184 | + default: | ||
185 | + // This should never happen. | ||
186 | + res.writeHead(500, ''); | ||
187 | + res.end(); | ||
188 | + } | ||
189 | +} | ||
190 | + | ||
191 | +/** | ||
192 | + * Determine whether or not a cached value must be revalidated. | ||
193 | + * | ||
194 | + * @param {Object} req | ||
195 | + * @param {Object} cacheEntry | ||
196 | + * @return {String} | ||
197 | + * @api private | ||
198 | + */ | ||
199 | + | ||
200 | +function mustRevalidate(req, cacheEntry) { | ||
201 | + var cacheHeaders = cacheEntry[1] | ||
202 | + , reqCC = utils.parseCacheControl(req.headers['cache-control'] || '') | ||
203 | + , cacheCC = utils.parseCacheControl(cacheHeaders['cache-control'] || '') | ||
204 | + , cacheAge = (new Date - new Date(cacheHeaders.date)) / 1000 || 0; | ||
205 | + | ||
206 | + if ( cacheCC['no-cache'] | ||
207 | + || cacheCC['must-revalidate'] | ||
208 | + || cacheCC['proxy-revalidate']) return true; | ||
209 | + | ||
210 | + if (reqCC['no-cache']) return true; | ||
211 | + | ||
212 | + if (null != reqCC['max-age']) return reqCC['max-age'] < cacheAge; | ||
213 | + | ||
214 | + if (null != cacheCC['max-age']) return cacheCC['max-age'] < cacheAge; | ||
215 | + | ||
216 | + return false; | ||
217 | +} | ||
218 | + | ||
219 | +/** | ||
220 | + * The key to use in the cache. For now, this is the URL path and query. | ||
221 | + * | ||
222 | + * 'http://example.com?key=value' -> '/?key=value' | ||
223 | + * | ||
224 | + * @param {Object} req | ||
225 | + * @return {String} | ||
226 | + * @api private | ||
227 | + */ | ||
228 | + | ||
229 | +function cacheKey(req) { | ||
230 | + return utils.parseUrl(req).path; | ||
231 | +} |
1 | +/*! | ||
2 | + * Connect - timeout | ||
3 | + * Ported from https://github.com/LearnBoost/connect-timeout | ||
4 | + * MIT Licensed | ||
5 | + */ | ||
6 | + | ||
7 | +/** | ||
8 | + * Module dependencies. | ||
9 | + */ | ||
10 | + | ||
11 | +var debug = require('debug')('connect:timeout'); | ||
12 | + | ||
13 | +/** | ||
14 | + * Timeout: | ||
15 | + * | ||
16 | + * Times out the request in `ms`, defaulting to `5000`. The | ||
17 | + * method `req.clearTimeout()` is added to revert this behaviour | ||
18 | + * programmatically within your application's middleware, routes, etc. | ||
19 | + * | ||
20 | + * The timeout error is passed to `next()` so that you may customize | ||
21 | + * the response behaviour. This error has the `.timeout` property as | ||
22 | + * well as `.status == 503`. | ||
23 | + * | ||
24 | + * @param {Number} ms | ||
25 | + * @return {Function} | ||
26 | + * @api public | ||
27 | + */ | ||
28 | + | ||
29 | +module.exports = function timeout(ms) { | ||
30 | + ms = ms || 5000; | ||
31 | + | ||
32 | + return function(req, res, next) { | ||
33 | + var id = setTimeout(function(){ | ||
34 | + req.emit('timeout', ms); | ||
35 | + }, ms); | ||
36 | + | ||
37 | + req.on('timeout', function(){ | ||
38 | + if (res.headerSent) return debug('response started, cannot timeout'); | ||
39 | + var err = new Error('Response timeout'); | ||
40 | + err.timeout = ms; | ||
41 | + err.status = 503; | ||
42 | + next(err); | ||
43 | + }); | ||
44 | + | ||
45 | + req.clearTimeout = function(){ | ||
46 | + clearTimeout(id); | ||
47 | + }; | ||
48 | + | ||
49 | + res.on('header', function(){ | ||
50 | + clearTimeout(id); | ||
51 | + }); | ||
52 | + | ||
53 | + next(); | ||
54 | + }; | ||
55 | +}; |
1 | + | ||
2 | +/*! | ||
3 | + * Connect - urlencoded | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var utils = require('../utils') | ||
14 | + , _limit = require('./limit') | ||
15 | + , qs = require('qs'); | ||
16 | + | ||
17 | +/** | ||
18 | + * noop middleware. | ||
19 | + */ | ||
20 | + | ||
21 | +function noop(req, res, next) { | ||
22 | + next(); | ||
23 | +} | ||
24 | + | ||
25 | +/** | ||
26 | + * Urlencoded: | ||
27 | + * | ||
28 | + * Parse x-ww-form-urlencoded request bodies, | ||
29 | + * providing the parsed object as `req.body`. | ||
30 | + * | ||
31 | + * Options: | ||
32 | + * | ||
33 | + * - `limit` byte limit disabled by default | ||
34 | + * | ||
35 | + * @param {Object} options | ||
36 | + * @return {Function} | ||
37 | + * @api public | ||
38 | + */ | ||
39 | + | ||
40 | +exports = module.exports = function(options){ | ||
41 | + options = options || {}; | ||
42 | + | ||
43 | + var limit = options.limit | ||
44 | + ? _limit(options.limit) | ||
45 | + : noop; | ||
46 | + | ||
47 | + return function urlencoded(req, res, next) { | ||
48 | + if (req._body) return next(); | ||
49 | + req.body = req.body || {}; | ||
50 | + | ||
51 | + if (!utils.hasBody(req)) return next(); | ||
52 | + | ||
53 | + // check Content-Type | ||
54 | + if ('application/x-www-form-urlencoded' != utils.mime(req)) return next(); | ||
55 | + | ||
56 | + // flag as parsed | ||
57 | + req._body = true; | ||
58 | + | ||
59 | + // parse | ||
60 | + limit(req, res, function(err){ | ||
61 | + if (err) return next(err); | ||
62 | + var buf = ''; | ||
63 | + req.setEncoding('utf8'); | ||
64 | + req.on('data', function(chunk){ buf += chunk }); | ||
65 | + req.on('end', function(){ | ||
66 | + try { | ||
67 | + req.body = buf.length | ||
68 | + ? qs.parse(buf, options) | ||
69 | + : {}; | ||
70 | + } catch (err){ | ||
71 | + err.body = buf; | ||
72 | + return next(err); | ||
73 | + } | ||
74 | + next(); | ||
75 | + }); | ||
76 | + }); | ||
77 | + } | ||
78 | +}; |
node_modules/connect/lib/middleware/vhost.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect - vhost | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Vhost: | ||
11 | + * | ||
12 | + * Setup vhost for the given `hostname` and `server`. | ||
13 | + * | ||
14 | + * connect() | ||
15 | + * .use(connect.vhost('foo.com', fooApp)) | ||
16 | + * .use(connect.vhost('bar.com', barApp)) | ||
17 | + * .use(connect.vhost('*.com', mainApp)) | ||
18 | + * | ||
19 | + * The `server` may be a Connect server or | ||
20 | + * a regular Node `http.Server`. | ||
21 | + * | ||
22 | + * @param {String} hostname | ||
23 | + * @param {Server} server | ||
24 | + * @return {Function} | ||
25 | + * @api public | ||
26 | + */ | ||
27 | + | ||
28 | +module.exports = function vhost(hostname, server){ | ||
29 | + if (!hostname) throw new Error('vhost hostname required'); | ||
30 | + if (!server) throw new Error('vhost server required'); | ||
31 | + var regexp = new RegExp('^' + hostname.replace(/[^*\w]/g, '\\$&').replace(/[*]/g, '(?:.*?)') + '$', 'i'); | ||
32 | + if (server.onvhost) server.onvhost(hostname); | ||
33 | + return function vhost(req, res, next){ | ||
34 | + if (!req.headers.host) return next(); | ||
35 | + var host = req.headers.host.split(':')[0]; | ||
36 | + if (!regexp.test(host)) return next(); | ||
37 | + if ('function' == typeof server) return server(req, res, next); | ||
38 | + server.emit('request', req, res); | ||
39 | + }; | ||
40 | +}; |
node_modules/connect/lib/patch.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect | ||
4 | + * Copyright(c) 2011 TJ Holowaychuk | ||
5 | + * MIT Licensed | ||
6 | + */ | ||
7 | + | ||
8 | +/** | ||
9 | + * Module dependencies. | ||
10 | + */ | ||
11 | + | ||
12 | +var http = require('http') | ||
13 | + , res = http.ServerResponse.prototype | ||
14 | + , setHeader = res.setHeader | ||
15 | + , _renderHeaders = res._renderHeaders | ||
16 | + , writeHead = res.writeHead; | ||
17 | + | ||
18 | +// apply only once | ||
19 | + | ||
20 | +if (!res._hasConnectPatch) { | ||
21 | + | ||
22 | + /** | ||
23 | + * Provide a public "header sent" flag | ||
24 | + * until node does. | ||
25 | + * | ||
26 | + * @return {Boolean} | ||
27 | + * @api public | ||
28 | + */ | ||
29 | + | ||
30 | + res.__defineGetter__('headerSent', function(){ | ||
31 | + return this._header; | ||
32 | + }); | ||
33 | + | ||
34 | + /** | ||
35 | + * Set header `field` to `val`, special-casing | ||
36 | + * the `Set-Cookie` field for multiple support. | ||
37 | + * | ||
38 | + * @param {String} field | ||
39 | + * @param {String} val | ||
40 | + * @api public | ||
41 | + */ | ||
42 | + | ||
43 | + res.setHeader = function(field, val){ | ||
44 | + var key = field.toLowerCase() | ||
45 | + , prev; | ||
46 | + | ||
47 | + // special-case Set-Cookie | ||
48 | + if (this._headers && 'set-cookie' == key) { | ||
49 | + if (prev = this.getHeader(field)) { | ||
50 | + val = Array.isArray(prev) | ||
51 | + ? prev.concat(val) | ||
52 | + : [prev, val]; | ||
53 | + } | ||
54 | + // charset | ||
55 | + } else if ('content-type' == key && this.charset) { | ||
56 | + val += '; charset=' + this.charset; | ||
57 | + } | ||
58 | + | ||
59 | + return setHeader.call(this, field, val); | ||
60 | + }; | ||
61 | + | ||
62 | + /** | ||
63 | + * Proxy to emit "header" event. | ||
64 | + */ | ||
65 | + | ||
66 | + res._renderHeaders = function(){ | ||
67 | + if (!this._emittedHeader) this.emit('header'); | ||
68 | + this._emittedHeader = true; | ||
69 | + return _renderHeaders.call(this); | ||
70 | + }; | ||
71 | + | ||
72 | + res.writeHead = function(){ | ||
73 | + if (!this._emittedHeader) this.emit('header'); | ||
74 | + this._emittedHeader = true; | ||
75 | + return writeHead.apply(this, arguments); | ||
76 | + }; | ||
77 | + | ||
78 | + res._hasConnectPatch = true; | ||
79 | +} |
node_modules/connect/lib/proto.js
0 → 100644
1 | + | ||
2 | +/*! | ||
3 | + * Connect - HTTPServer | ||
4 | + * Copyright(c) 2010 Sencha Inc. | ||
5 | + * Copyright(c) 2011 TJ Holowaychuk | ||
6 | + * MIT Licensed | ||
7 | + */ | ||
8 | + | ||
9 | +/** | ||
10 | + * Module dependencies. | ||
11 | + */ | ||
12 | + | ||
13 | +var http = require('http') | ||
14 | + , utils = require('./utils') | ||
15 | + , debug = require('debug')('connect:dispatcher'); | ||
16 | + | ||
17 | +// prototype | ||
18 | + | ||
19 | +var app = module.exports = {}; | ||
20 | + | ||
21 | +// environment | ||
22 | + | ||
23 | +var env = process.env.NODE_ENV || 'development'; | ||
24 | + | ||
25 | +/** | ||
26 | + * Utilize the given middleware `handle` to the given `route`, | ||
27 | + * defaulting to _/_. This "route" is the mount-point for the | ||
28 | + * middleware, when given a value other than _/_ the middleware | ||
29 | + * is only effective when that segment is present in the request's | ||
30 | + * pathname. | ||
31 | + * | ||
32 | + * For example if we were to mount a function at _/admin_, it would | ||
33 | + * be invoked on _/admin_, and _/admin/settings_, however it would | ||
34 | + * not be invoked for _/_, or _/posts_. | ||
35 | + * | ||
36 | + * Examples: | ||
37 | + * | ||
38 | + * var app = connect(); | ||
39 | + * app.use(connect.favicon()); | ||
40 | + * app.use(connect.logger()); | ||
41 | + * app.use(connect.static(__dirname + '/public')); | ||
42 | + * | ||
43 | + * If we wanted to prefix static files with _/public_, we could | ||
44 | + * "mount" the `static()` middleware: | ||
45 | + * | ||
46 | + * app.use('/public', connect.static(__dirname + '/public')); | ||
47 | + * | ||
48 | + * This api is chainable, so the following is valid: | ||
49 | + * | ||
50 | + * connect() | ||
51 | + * .use(connect.favicon()) | ||
52 | + * .use(connect.logger()) | ||
53 | + * .use(connect.static(__dirname + '/public')) | ||
54 | + * .listen(3000); | ||
55 | + * | ||
56 | + * @param {String|Function|Server} route, callback or server | ||
57 | + * @param {Function|Server} callback or server | ||
58 | + * @return {Server} for chaining | ||
59 | + * @api public | ||
60 | + */ | ||
61 | + | ||
62 | +app.use = function(route, fn){ | ||
63 | + // default route to '/' | ||
64 | + if ('string' != typeof route) { | ||
65 | + fn = route; | ||
66 | + route = '/'; | ||
67 | + } | ||
68 | + | ||
69 | + // wrap sub-apps | ||
70 | + if ('function' == typeof fn.handle) { | ||
71 | + var server = fn; | ||
72 | + fn.route = route; | ||
73 | + fn = function(req, res, next){ | ||
74 | + server.handle(req, res, next); | ||
75 | + }; | ||
76 | + } | ||
77 | + | ||
78 | + // wrap vanilla http.Servers | ||
79 | + if (fn instanceof http.Server) { | ||
80 | + fn = fn.listeners('request')[0]; | ||
81 | + } | ||
82 | + | ||
83 | + // strip trailing slash | ||
84 | + if ('/' == route[route.length - 1]) { | ||
85 | + route = route.slice(0, -1); | ||
86 | + } | ||
87 | + | ||
88 | + // add the middleware | ||
89 | + debug('use %s %s', route || '/', fn.name || 'anonymous'); | ||
90 | + this.stack.push({ route: route, handle: fn }); | ||
91 | + | ||
92 | + return this; | ||
93 | +}; | ||
94 | + | ||
95 | +/** | ||
96 | + * Handle server requests, punting them down | ||
97 | + * the middleware stack. | ||
98 | + * | ||
99 | + * @api private | ||
100 | + */ | ||
101 | + | ||
102 | +app.handle = function(req, res, out) { | ||
103 | + var stack = this.stack | ||
104 | + , fqdn = ~req.url.indexOf('://') | ||
105 | + , removed = '' | ||
106 | + , slashAdded = false | ||
107 | + , index = 0; | ||
108 | + | ||
109 | + function next(err) { | ||
110 | + var layer, path, status, c; | ||
111 | + | ||
112 | + if (slashAdded) { | ||
113 | + req.url = req.url.substr(1); | ||
114 | + slashAdded = false; | ||
115 | + } | ||
116 | + | ||
117 | + req.url = removed + req.url; | ||
118 | + req.originalUrl = req.originalUrl || req.url; | ||
119 | + removed = ''; | ||
120 | + | ||
121 | + // next callback | ||
122 | + layer = stack[index++]; | ||
123 | + | ||
124 | + // all done | ||
125 | + if (!layer || res.headerSent) { | ||
126 | + // delegate to parent | ||
127 | + if (out) return out(err); | ||
128 | + | ||
129 | + // unhandled error | ||
130 | + if (err) { | ||
131 | + // default to 500 | ||
132 | + if (res.statusCode < 400) res.statusCode = 500; | ||
133 | + debug('default %s', res.statusCode); | ||
134 | + | ||
135 | + // respect err.status | ||
136 | + if (err.status) res.statusCode = err.status; | ||
137 | + | ||
138 | + // production gets a basic error message | ||
139 | + var msg = 'production' == env | ||
140 | + ? http.STATUS_CODES[res.statusCode] | ||
141 | + : err.stack || err.toString(); | ||
142 | + | ||
143 | + // log to stderr in a non-test env | ||
144 | + if ('test' != env) console.error(err.stack || err.toString()); | ||
145 | + if (res.headerSent) return req.socket.destroy(); | ||
146 | + res.setHeader('Content-Type', 'text/plain'); | ||
147 | + res.setHeader('Content-Length', Buffer.byteLength(msg)); | ||
148 | + if ('HEAD' == req.method) return res.end(); | ||
149 | + res.end(msg); | ||
150 | + } else { | ||
151 | + debug('default 404'); | ||
152 | + res.statusCode = 404; | ||
153 | + res.setHeader('Content-Type', 'text/plain'); | ||
154 | + if ('HEAD' == req.method) return res.end(); | ||
155 | + res.end('Cannot ' + utils.escape(req.method) + ' ' + utils.escape(req.originalUrl)); | ||
156 | + } | ||
157 | + return; | ||
158 | + } | ||
159 | + | ||
160 | + try { | ||
161 | + path = utils.parseUrl(req).pathname; | ||
162 | + if (undefined == path) path = '/'; | ||
163 | + | ||
164 | + // skip this layer if the route doesn't match. | ||
165 | + if (0 != path.toLowerCase().indexOf(layer.route.toLowerCase())) return next(err); | ||
166 | + | ||
167 | + c = path[layer.route.length]; | ||
168 | + if (c && '/' != c && '.' != c) return next(err); | ||
169 | + | ||
170 | + // Call the layer handler | ||
171 | + // Trim off the part of the url that matches the route | ||
172 | + removed = layer.route; | ||
173 | + req.url = req.url.substr(removed.length); | ||
174 | + | ||
175 | + // Ensure leading slash | ||
176 | + if (!fqdn && '/' != req.url[0]) { | ||
177 | + req.url = '/' + req.url; | ||
178 | + slashAdded = true; | ||
179 | + } | ||
180 | + | ||
181 | + debug('%s %s : %s', layer.handle.name || 'anonymous', layer.route, req.originalUrl); | ||
182 | + var arity = layer.handle.length; | ||
183 | + if (err) { | ||
184 | + if (arity === 4) { | ||
185 | + layer.handle(err, req, res, next); | ||
186 | + } else { | ||
187 | + next(err); | ||
188 | + } | ||
189 | + } else if (arity < 4) { | ||
190 | + layer.handle(req, res, next); | ||
191 | + } else { | ||
192 | + next(); | ||
193 | + } | ||
194 | + } catch (e) { | ||
195 | + next(e); | ||
196 | + } | ||
197 | + } | ||
198 | + next(); | ||
199 | +}; | ||
200 | + | ||
201 | +/** | ||
202 | + * Listen for connections. | ||
203 | + * | ||
204 | + * This method takes the same arguments | ||
205 | + * as node's `http.Server#listen()`. | ||
206 | + * | ||
207 | + * HTTP and HTTPS: | ||
208 | + * | ||
209 | + * If you run your application both as HTTP | ||
210 | + * and HTTPS you may wrap them individually, | ||
211 | + * since your Connect "server" is really just | ||
212 | + * a JavaScript `Function`. | ||
213 | + * | ||
214 | + * var connect = require('connect') | ||
215 | + * , http = require('http') | ||
216 | + * , https = require('https'); | ||
217 | + * | ||
218 | + * var app = connect(); | ||
219 | + * | ||
220 | + * http.createServer(app).listen(80); | ||
221 | + * https.createServer(options, app).listen(443); | ||
222 | + * | ||
223 | + * @return {http.Server} | ||
224 | + * @api public | ||
225 | + */ | ||
226 | + | ||
227 | +app.listen = function(){ | ||
228 | + var server = http.createServer(this); | ||
229 | + return server.listen.apply(server, arguments); | ||
230 | +}; |
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | + <head> | ||
4 | + <meta charset='utf-8'> | ||
5 | + <title>listing directory {directory}</title> | ||
6 | + <style>{style}</style> | ||
7 | + <script> | ||
8 | + function $(id){ | ||
9 | + var el = 'string' == typeof id | ||
10 | + ? document.getElementById(id) | ||
11 | + : id; | ||
12 | + | ||
13 | + el.on = function(event, fn){ | ||
14 | + if ('content loaded' == event) { | ||
15 | + event = window.attachEvent ? "load" : "DOMContentLoaded"; | ||
16 | + } | ||
17 | + el.addEventListener | ||
18 | + ? el.addEventListener(event, fn, false) | ||
19 | + : el.attachEvent("on" + event, fn); | ||
20 | + }; | ||
21 | + | ||
22 | + el.all = function(selector){ | ||
23 | + return $(el.querySelectorAll(selector)); | ||
24 | + }; | ||
25 | + | ||
26 | + el.each = function(fn){ | ||
27 | + for (var i = 0, len = el.length; i < len; ++i) { | ||
28 | + fn($(el[i]), i); | ||
29 | + } | ||
30 | + }; | ||
31 | + | ||
32 | + el.getClasses = function(){ | ||
33 | + return this.getAttribute('class').split(/\s+/); | ||
34 | + }; | ||
35 | + | ||
36 | + el.addClass = function(name){ | ||
37 | + var classes = this.getAttribute('class'); | ||
38 | + el.setAttribute('class', classes | ||
39 | + ? classes + ' ' + name | ||
40 | + : name); | ||
41 | + }; | ||
42 | + | ||
43 | + el.removeClass = function(name){ | ||
44 | + var classes = this.getClasses().filter(function(curr){ | ||
45 | + return curr != name; | ||
46 | + }); | ||
47 | + this.setAttribute('class', classes); | ||
48 | + }; | ||
49 | + | ||
50 | + return el; | ||
51 | + } | ||
52 | + | ||
53 | + function search() { | ||
54 | + var str = $('search').value | ||
55 | + , links = $('files').all('a'); | ||
56 | + | ||
57 | + links.each(function(link){ | ||
58 | + var text = link.textContent; | ||
59 | + | ||
60 | + if ('..' == text) return; | ||
61 | + if (str.length && ~text.indexOf(str)) { | ||
62 | + link.addClass('highlight'); | ||
63 | + } else { | ||
64 | + link.removeClass('highlight'); | ||
65 | + } | ||
66 | + }); | ||
67 | + } | ||
68 | + | ||
69 | + $(window).on('content loaded', function(){ | ||
70 | + $('search').on('keyup', search); | ||
71 | + }); | ||
72 | + </script> | ||
73 | + </head> | ||
74 | + <body class="directory"> | ||
75 | + <input id="search" type="text" placeholder="Search" autocomplete="off" /> | ||
76 | + <div id="wrapper"> | ||
77 | + <h1>{linked-path}</h1> | ||
78 | + {files} | ||
79 | + </div> | ||
80 | + </body> | ||
81 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
node_modules/connect/lib/public/error.html
0 → 100644
node_modules/connect/lib/public/favicon.ico
0 → 100644
No preview for this file type

635 Bytes

739 Bytes

794 Bytes

818 Bytes

663 Bytes

740 Bytes

807 Bytes

793 Bytes

817 Bytes

879 Bytes

833 Bytes

779 Bytes

621 Bytes

801 Bytes

839 Bytes

830 Bytes

813 Bytes

703 Bytes

641 Bytes

858 Bytes

774 Bytes

294 Bytes

591 Bytes

664 Bytes

512 Bytes

587 Bytes

656 Bytes

666 Bytes

603 Bytes

587 Bytes

592 Bytes

724 Bytes

309 Bytes

621 Bytes

700 Bytes

639 Bytes

579 Bytes

536 Bytes

638 Bytes

618 Bytes

623 Bytes

663 Bytes

676 Bytes

582 Bytes

639 Bytes

402 Bytes

516 Bytes

612 Bytes

603 Bytes

296 Bytes

616 Bytes

669 Bytes

614 Bytes

554 Bytes

706 Bytes

779 Bytes

688 Bytes

618 Bytes

620 Bytes

538 Bytes

650 Bytes

588 Bytes

523 Bytes

626 Bytes

317 Bytes

565 Bytes

634 Bytes

342 Bytes

315 Bytes

668 Bytes

644 Bytes

702 Bytes

309 Bytes

651 Bytes

734 Bytes

613 Bytes

386 Bytes

777 Bytes

903 Bytes
node_modules/connect/lib/public/style.css
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/connect/lib/utils.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/connect/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/connect/test.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/cookie-session/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookie-session/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookie-session/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookie-session/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookie-session/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookies/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookies/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookies/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookies/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/cookies/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/float.patch
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/lib/util.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/core-util-is/test.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/express-session/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/express-session/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/express-session/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/express-session/index.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/express-session/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/.npmignore
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/.travis.yml
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/Readme.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/example/json.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/example/post.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/example/upload.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/lib/file.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/lib/incoming_form.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/lib/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/lib/json_parser.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/lib/octet_parser.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/formidable/test/common.js
0 → 100644
This diff is collapsed. Click to expand it.

1.62 KB
No preview for this file type

49 Bytes
This diff is collapsed. Click to expand it.

931 Bytes
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/test/run.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/formidable/tool/record.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/google-calendar/.npmignore
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/LICENSE.txt
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/google-calendar/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/node_modules/passport-google-oauth/lib/passport-google-oauth/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/google-calendar/node_modules/passport-google-oauth/lib/passport-google-oauth/oauth.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/google-calendar/node_modules/passport-google-oauth/lib/passport-google-oauth/oauth2.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/node_modules/passport/lib/passport/middleware/authenticate.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/google-calendar/specs/config.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/isarray/.npmignore
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/.travis.yml
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/Makefile
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/component.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/isarray/test.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keygrip/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keygrip/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keygrip/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keygrip/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keygrip/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keypress/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keypress/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keypress/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/keypress/test.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/Changes.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/License
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/Readme.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/Connection.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/ConnectionConfig.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/Pool.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/PoolCluster.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/PoolConfig.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/PoolConnection.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/PoolNamespace.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/PoolSelector.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/Auth.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/Parser.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/Protocol.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/ResultSet.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/SqlString.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/mysql/lib/protocol/Timer.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/mysql/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/bin/needle
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/needle/examples/digest-auth.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/needle/examples/upload-image.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/auth.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/cookies.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/decoder.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/multipart.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/needle.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/parsers.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/lib/querystring.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/license.txt
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/needle/node_modules/ms/index.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/needle/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/basic_auth_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/compression_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/cookies_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/decoder_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/errors_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/headers_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/helpers.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/long_string_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/output_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/parsing_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/post_data_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/proxy_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/querystring_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/redirect_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/needle/test/socket_pool_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/url_spec.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/utils/formidable.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/utils/proxy.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/needle/test/utils/test.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/node_modules/passport-google-oauth20/.github/ISSUE_TEMPLATE.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/node_modules/passport-google-oauth20/lib/errors/userinfoerror.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/node_modules/passport-google-oauth20/lib/profile/googleplus.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth/node_modules/passport-google-oauth20/lib/profile/openid.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-google-oauth1/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-oauth/.travis.yml
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-oauth/node_modules/passport/lib/passport/middleware/authenticate.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-oauth/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/.npmignore
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/lib/index.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/lib/strategy.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/lib/utils.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/passport-oauth1/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/pkginfo/.npmignore
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/pkginfo/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/pkginfo/docs/docco.css
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/pkginfo/docs/pkginfo.html
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/pkginfo/examples/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/pkginfo/lib/pkginfo.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/pkginfo/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/pkginfo/test/pkginfo-test.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/process-nextick-args/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/process-nextick-args/license.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/process-nextick-args/readme.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/random-bytes/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/random-bytes/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/random-bytes/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/random-bytes/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/random-bytes/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/.travis.yml
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/CONTRIBUTING.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/GOVERNANCE.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/readable-stream/duplex.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/readable-stream/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/passthrough.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/readable-stream/readable.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/readable-stream/transform.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/readable-stream/writable.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sax/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sax/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sax/lib/sax.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sax/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/lib/SqlString.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/sqlstring/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/string_decoder/.travis.yml
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/string_decoder/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/string_decoder/README.md
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
node_modules/string_decoder/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/uid-safe/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/uid-safe/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/uid-safe/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/uid-safe/index.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/uid-safe/package.json
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/History.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/README.md
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/browser.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/node.js
0 → 100644
This diff is collapsed. Click to expand it.
node_modules/util-deprecate/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
routes/login.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment