vulcan 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/vulcan +3 -1
- data/lib/vulcan/cli.rb +22 -3
- data/lib/vulcan/version.rb +1 -1
- data/server/bin/make +1 -3
- data/server/lib/spawner.js +9 -4
- data/server/node_modules/connect-form/node_modules/formidable/Readme.md +13 -2
- data/server/node_modules/connect-form/node_modules/formidable/lib/incoming_form.js +19 -7
- data/server/node_modules/connect-form/node_modules/formidable/lib/multipart_parser.js +12 -1
- data/server/node_modules/connect-form/node_modules/formidable/package.json +1 -1
- data/server/node_modules/connect-form/node_modules/formidable/test/fixture/file/plain.txt +1 -0
- data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/no-filename/generic.http +13 -0
- data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +0 -10
- data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +0 -9
- data/server/node_modules/connect-form/node_modules/formidable/test/fixture/js/no-filename.js +3 -0
- data/server/node_modules/connect-form/node_modules/formidable/test/legacy/simple/test-multipart-parser.js +1 -1
- data/server/node_modules/cradle/lib/cradle.js +0 -1
- data/server/node_modules/cradle/package.json +3 -3
- data/server/node_modules/cradle/test/cache-test.js +6 -7
- data/server/node_modules/cradle/test/cradle-test.js +4 -5
- data/server/node_modules/cradle/test/response-test.js +5 -6
- data/server/node_modules/express/History.md +53 -1
- data/server/node_modules/express/Makefile +3 -9
- data/server/node_modules/express/Readme.md +3 -1
- data/server/node_modules/express/bin/express +65 -66
- data/server/node_modules/express/lib/express.js +1 -1
- data/server/node_modules/express/lib/request.js +23 -9
- data/server/node_modules/express/lib/response.js +3 -2
- data/server/node_modules/express/lib/utils.js +13 -0
- data/server/node_modules/express/lib/view/view.js +2 -1
- data/server/node_modules/express/lib/view.js +19 -16
- data/server/node_modules/express/node_modules/connect/lib/connect.js +1 -1
- data/server/node_modules/express/node_modules/connect/lib/http.js +2 -0
- data/server/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js +135 -31
- data/server/node_modules/express/node_modules/connect/lib/middleware/limit.js +5 -1
- data/server/node_modules/express/node_modules/connect/lib/middleware/session.js +2 -2
- data/server/node_modules/express/node_modules/connect/lib/middleware/static.js +26 -21
- data/server/node_modules/express/node_modules/connect/lib/middleware/staticCache.js +91 -38
- data/server/node_modules/express/node_modules/connect/lib/middleware/vhost.js +1 -1
- data/server/node_modules/express/node_modules/connect/lib/utils.js +11 -4
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/Makefile +14 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md +286 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/TODO +3 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js +70 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js +43 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js +48 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/index.js +1 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js +61 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js +377 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js +3 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js +312 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js +25 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js +6 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/package.json +22 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js +19 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt +1 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt +1 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/no-filename/generic.http +13 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md +3 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +26 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http +24 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +23 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +24 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +22 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +22 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +22 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js +3 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +21 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multi_video.upload +0 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js +72 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js +89 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js +24 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js +80 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js +104 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +715 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js +50 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js +45 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js +72 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js +2 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js +63 -0
- data/server/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js +47 -0
- data/server/node_modules/express/node_modules/connect/package.json +7 -6
- data/server/node_modules/express/node_modules/connect/test.js +44 -31
- data/server/node_modules/express/node_modules/mime/mime.js +3 -3
- data/server/node_modules/express/node_modules/mime/package.json +21 -10
- data/server/node_modules/express/node_modules/mime/test.js +2 -3
- data/server/node_modules/express/node_modules/mime/{mime.types → types/mime.types} +0 -0
- data/server/node_modules/express/node_modules/mime/{node.types → types/node.types} +17 -0
- data/server/node_modules/express/node_modules/mkdirp/LICENSE +21 -0
- data/server/node_modules/express/node_modules/mkdirp/README.markdown +21 -0
- data/server/node_modules/express/node_modules/mkdirp/examples/pow.js +6 -0
- data/server/node_modules/express/node_modules/mkdirp/examples/pow.js.orig +6 -0
- data/server/node_modules/express/node_modules/mkdirp/examples/pow.js.rej +19 -0
- data/server/node_modules/express/node_modules/mkdirp/index.js +20 -0
- data/server/node_modules/express/node_modules/mkdirp/package.json +23 -0
- data/server/node_modules/express/node_modules/mkdirp/test/mkdirp.js +28 -0
- data/server/node_modules/express/node_modules/mkdirp/test/race.js +41 -0
- data/server/node_modules/express/node_modules/mkdirp/test/rel.js +32 -0
- data/server/node_modules/express/node_modules/qs/History.md +11 -0
- data/server/node_modules/express/node_modules/qs/Makefile +1 -3
- data/server/node_modules/express/node_modules/qs/Readme.md +2 -4
- data/server/node_modules/express/node_modules/qs/lib/querystring.js +100 -74
- data/server/node_modules/express/node_modules/qs/package.json +9 -2
- data/server/node_modules/express/node_modules/qs/test/mocha.opts +2 -0
- data/server/node_modules/express/node_modules/qs/test/{parse.test.js → parse.js} +1 -2
- data/server/node_modules/express/node_modules/qs/test/{stringify.test.js → stringify.js} +0 -0
- data/server/node_modules/express/package.json +9 -8
- data/server/node_modules/express/testing/foo/app.js +35 -0
- data/server/node_modules/express/testing/foo/package.json +9 -0
- data/server/node_modules/express/testing/foo/public/stylesheets/style.css +8 -0
- data/server/node_modules/express/testing/foo/routes/index.js +10 -0
- data/server/node_modules/express/testing/foo/views/index.jade +2 -0
- data/server/node_modules/express/testing/foo/views/layout.jade +6 -0
- data/server/node_modules/express/testing/index.js +43 -0
- data/server/node_modules/express/testing/public/test.txt +2971 -0
- data/server/node_modules/express/testing/views/page.html +1 -0
- data/server/node_modules/express/testing/views/page.jade +3 -0
- data/server/node_modules/express/testing/views/test.md +1 -0
- data/server/node_modules/express/testing/views/user/index.jade +1 -0
- data/server/node_modules/express/testing/views/user/list.jade +1 -0
- data/server/node_modules/node-uuid/README.md +166 -67
- data/server/node_modules/node-uuid/benchmark/README.md +53 -0
- data/server/node_modules/node-uuid/benchmark/bench.gnu +174 -0
- data/server/node_modules/node-uuid/benchmark/bench.sh +34 -0
- data/server/node_modules/node-uuid/{test → benchmark}/benchmark-native.c +0 -0
- data/server/node_modules/node-uuid/benchmark/benchmark.js +84 -0
- data/server/node_modules/node-uuid/package.json +5 -3
- data/server/node_modules/node-uuid/test/benchmark-native +0 -0
- data/server/node_modules/node-uuid/test/compare_v1.js +63 -0
- data/server/node_modules/node-uuid/test/test.html +3 -0
- data/server/node_modules/node-uuid/test/test.js +214 -57
- data/server/node_modules/node-uuid/uuid.js +225 -56
- data/server/node_modules/restler/README.md +20 -7
- data/server/node_modules/restler/bin/restler +1 -1
- data/server/node_modules/restler/lib/multipartform.js +9 -8
- data/server/node_modules/restler/lib/restler.js +64 -22
- data/server/node_modules/restler/package.json +2 -2
- data/server/node_modules/restler/test/restler.js +22 -2
- data/server/node_modules/restler/test/test_helper.js +20 -1
- data/server/package.json +1 -2
- data/server/web.js +30 -7
- metadata +90 -86
- data/server/node_modules/cradle/node_modules/vows/LICENSE +0 -20
- data/server/node_modules/cradle/node_modules/vows/Makefile +0 -7
- data/server/node_modules/cradle/node_modules/vows/README.md +0 -39
- data/server/node_modules/cradle/node_modules/vows/bin/vows +0 -515
- data/server/node_modules/cradle/node_modules/vows/lib/assert/error.js +0 -27
- data/server/node_modules/cradle/node_modules/vows/lib/assert/macros.js +0 -215
- data/server/node_modules/cradle/node_modules/vows/lib/assert/utils.js +0 -77
- data/server/node_modules/cradle/node_modules/vows/lib/vows/console.js +0 -131
- data/server/node_modules/cradle/node_modules/vows/lib/vows/context.js +0 -55
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/file.js +0 -29
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/fragments/coverage-foot.html +0 -2
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/fragments/coverage-head.html +0 -61
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-html.js +0 -54
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-json.js +0 -54
- data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-plain.js +0 -38
- data/server/node_modules/cradle/node_modules/vows/lib/vows/extras.js +0 -28
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/dot-matrix.js +0 -67
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/json.js +0 -16
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/silent.js +0 -8
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/spec.js +0 -44
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/watch.js +0 -39
- data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/xunit.js +0 -90
- data/server/node_modules/cradle/node_modules/vows/lib/vows/suite.js +0 -319
- data/server/node_modules/cradle/node_modules/vows/lib/vows.js +0 -193
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/LICENSE +0 -20
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/Makefile +0 -4
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/README.md +0 -72
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/lib/eyes.js +0 -233
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/package.json +0 -14
- data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/test/eyes-test.js +0 -55
- data/server/node_modules/cradle/node_modules/vows/package.json +0 -14
- data/server/node_modules/cradle/node_modules/vows/test/assert-test.js +0 -135
- data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/failing.js +0 -18
- data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/log.js +0 -18
- data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/passing.js +0 -17
- data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/stderr.js +0 -18
- data/server/node_modules/cradle/node_modules/vows/test/isolate-test.js +0 -140
- data/server/node_modules/cradle/node_modules/vows/test/testInherit.js +0 -133
- data/server/node_modules/cradle/node_modules/vows/test/vows-error-test.js +0 -51
- data/server/node_modules/cradle/node_modules/vows/test/vows-test.js +0 -374
- data/server/node_modules/express/node_modules/mime/index.js +0 -1
- data/server/node_modules/express/node_modules/qs/support/expresso/History.md +0 -128
- data/server/node_modules/express/node_modules/qs/support/expresso/Makefile +0 -53
- data/server/node_modules/express/node_modules/qs/support/expresso/Readme.md +0 -61
- data/server/node_modules/express/node_modules/qs/support/expresso/bin/expresso +0 -856
- data/server/node_modules/express/node_modules/qs/support/expresso/docs/api.html +0 -1080
- data/server/node_modules/express/node_modules/qs/support/expresso/docs/index.html +0 -377
- data/server/node_modules/express/node_modules/qs/support/expresso/docs/index.md +0 -290
- data/server/node_modules/express/node_modules/qs/support/expresso/docs/layout/foot.html +0 -3
- data/server/node_modules/express/node_modules/qs/support/expresso/docs/layout/head.html +0 -42
- data/server/node_modules/express/node_modules/qs/support/expresso/lib/bar.js +0 -4
- data/server/node_modules/express/node_modules/qs/support/expresso/lib/foo.js +0 -16
- data/server/node_modules/express/node_modules/qs/support/expresso/package.json +0 -12
- data/server/node_modules/express/node_modules/qs/support/expresso/test/assert.test.js +0 -91
- data/server/node_modules/express/node_modules/qs/support/expresso/test/async.test.js +0 -12
- data/server/node_modules/express/node_modules/qs/support/expresso/test/bar.test.js +0 -13
- data/server/node_modules/express/node_modules/qs/support/expresso/test/foo.test.js +0 -14
- data/server/node_modules/express/node_modules/qs/support/expresso/test/http.test.js +0 -146
- data/server/node_modules/express/node_modules/qs/support/expresso/test/serial/async.test.js +0 -39
- data/server/node_modules/express/node_modules/qs/support/expresso/test/serial/http.test.js +0 -48
- data/server/node_modules/express/node_modules/qs/support/should/History.md +0 -22
- data/server/node_modules/express/node_modules/qs/support/should/Makefile +0 -6
- data/server/node_modules/express/node_modules/qs/support/should/Readme.md +0 -248
- data/server/node_modules/express/node_modules/qs/support/should/examples/runner.js +0 -53
- data/server/node_modules/express/node_modules/qs/support/should/index.js +0 -2
- data/server/node_modules/express/node_modules/qs/support/should/lib/eql.js +0 -91
- data/server/node_modules/express/node_modules/qs/support/should/lib/should.js +0 -548
- data/server/node_modules/express/node_modules/qs/support/should/package.json +0 -8
- data/server/node_modules/express/node_modules/qs/support/should/test/should.test.js +0 -358
- data/server/node_modules/node-uuid/test/benchmark.js +0 -27
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* Module dependencies.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
var qs = require('qs')
|
|
13
|
+
var qs = require('qs')
|
|
14
|
+
, formidable = require('formidable');
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Extract the mime type from the given request's
|
|
@@ -29,10 +30,9 @@ function mime(req) {
|
|
|
29
30
|
/**
|
|
30
31
|
* Parse request bodies.
|
|
31
32
|
*
|
|
32
|
-
* By default _application/json_
|
|
33
|
-
* are supported, however you may map `connect.bodyParser.parse[contentType]`
|
|
34
|
-
* to a function
|
|
35
|
-
* one for other content-types.
|
|
33
|
+
* By default _application/json_, _application/x-www-form-urlencoded_,
|
|
34
|
+
* and _multipart/form-data_ are supported, however you may map `connect.bodyParser.parse[contentType]`
|
|
35
|
+
* to a function receiving `(req, options, callback)`.
|
|
36
36
|
*
|
|
37
37
|
* Examples:
|
|
38
38
|
*
|
|
@@ -43,36 +43,52 @@ function mime(req) {
|
|
|
43
43
|
* }
|
|
44
44
|
* );
|
|
45
45
|
*
|
|
46
|
-
* Since both _json_ and _x-www-form-urlencoded_ are supported by
|
|
47
|
-
* default, either of the following requests would result in the response
|
|
48
|
-
* of "viewing user tj".
|
|
49
|
-
*
|
|
50
46
|
* $ curl -d 'user[name]=tj' http://localhost/
|
|
51
47
|
* $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://localhost/
|
|
52
48
|
*
|
|
49
|
+
* Multipart req.files:
|
|
50
|
+
*
|
|
51
|
+
* As a security measure files are stored in a separate object, stored
|
|
52
|
+
* as `req.files`. This prevents attacks that may potentially alter
|
|
53
|
+
* filenames, and depending on the application gain access to restricted files.
|
|
54
|
+
*
|
|
55
|
+
* Multipart configuration:
|
|
56
|
+
*
|
|
57
|
+
* The `options` passed are provided to each parser function.
|
|
58
|
+
* The _multipart/form-data_ parser merges these with formidable's
|
|
59
|
+
* IncomingForm object, allowing you to tweak the upload directory,
|
|
60
|
+
* size limits, etc. For example you may wish to retain the file extension
|
|
61
|
+
* and change the upload directory:
|
|
62
|
+
*
|
|
63
|
+
* server.use(bodyParser({ uploadDir: '/www/mysite.com/uploads' }));
|
|
64
|
+
*
|
|
65
|
+
* View [node-formidable](https://github.com/felixge/node-formidable) for more information.
|
|
66
|
+
*
|
|
67
|
+
* If you wish to use formidable directly within your app, and do not
|
|
68
|
+
* desire this behaviour for multipart requests simply remove the
|
|
69
|
+
* parser:
|
|
70
|
+
*
|
|
71
|
+
* delete connect.bodyParser.parse['multipart/form-data'];
|
|
72
|
+
*
|
|
73
|
+
* Or
|
|
74
|
+
*
|
|
75
|
+
* delete express.bodyParser.parse['multipart/form-data'];
|
|
76
|
+
*
|
|
77
|
+
* @param {Object} options
|
|
53
78
|
* @return {Function}
|
|
54
79
|
* @api public
|
|
55
80
|
*/
|
|
56
81
|
|
|
57
|
-
exports = module.exports = function bodyParser(){
|
|
82
|
+
exports = module.exports = function bodyParser(options){
|
|
83
|
+
options = options || {};
|
|
58
84
|
return function bodyParser(req, res, next) {
|
|
85
|
+
if (req.body) return next();
|
|
86
|
+
req.body = {};
|
|
87
|
+
|
|
59
88
|
if ('GET' == req.method || 'HEAD' == req.method) return next();
|
|
60
89
|
var parser = exports.parse[mime(req)];
|
|
61
|
-
if (parser
|
|
62
|
-
|
|
63
|
-
req.setEncoding('utf8');
|
|
64
|
-
req.on('data', function(chunk) { data += chunk; });
|
|
65
|
-
req.on('end', function(){
|
|
66
|
-
req.rawBody = data;
|
|
67
|
-
try {
|
|
68
|
-
req.body = data
|
|
69
|
-
? parser(data)
|
|
70
|
-
: {};
|
|
71
|
-
} catch (err) {
|
|
72
|
-
return next(err);
|
|
73
|
-
}
|
|
74
|
-
next();
|
|
75
|
-
});
|
|
90
|
+
if (parser) {
|
|
91
|
+
parser(req, options, next);
|
|
76
92
|
} else {
|
|
77
93
|
next();
|
|
78
94
|
}
|
|
@@ -80,13 +96,101 @@ exports = module.exports = function bodyParser(){
|
|
|
80
96
|
};
|
|
81
97
|
|
|
82
98
|
/**
|
|
83
|
-
*
|
|
99
|
+
* Parsers.
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
exports.parse = {};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Parse application/x-www-form-urlencoded.
|
|
106
|
+
*/
|
|
107
|
+
|
|
108
|
+
exports.parse['application/x-www-form-urlencoded'] = function(req, options, fn){
|
|
109
|
+
var buf = '';
|
|
110
|
+
req.setEncoding('utf8');
|
|
111
|
+
req.on('data', function(chunk){ buf += chunk });
|
|
112
|
+
req.on('end', function(){
|
|
113
|
+
try {
|
|
114
|
+
req.body = buf.length
|
|
115
|
+
? qs.parse(buf)
|
|
116
|
+
: {};
|
|
117
|
+
fn();
|
|
118
|
+
} catch (err){
|
|
119
|
+
fn(err);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Parse application/json.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
exports.parse['application/json'] = function(req, options, fn){
|
|
129
|
+
var buf = '';
|
|
130
|
+
req.setEncoding('utf8');
|
|
131
|
+
req.on('data', function(chunk){ buf += chunk });
|
|
132
|
+
req.on('end', function(){
|
|
133
|
+
try {
|
|
134
|
+
req.body = buf.length
|
|
135
|
+
? JSON.parse(buf)
|
|
136
|
+
: {};
|
|
137
|
+
fn();
|
|
138
|
+
} catch (err){
|
|
139
|
+
fn(err);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Parse multipart/form-data.
|
|
84
146
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
147
|
+
* TODO: make multiple support optional
|
|
148
|
+
* TODO: revisit "error" flag if it's a formidable bug
|
|
87
149
|
*/
|
|
88
150
|
|
|
89
|
-
exports.parse = {
|
|
90
|
-
|
|
91
|
-
|
|
151
|
+
exports.parse['multipart/form-data'] = function(req, options, fn){
|
|
152
|
+
var form = new formidable.IncomingForm
|
|
153
|
+
, data = {}
|
|
154
|
+
, files = {}
|
|
155
|
+
, done;
|
|
156
|
+
|
|
157
|
+
Object.keys(options).forEach(function(key){
|
|
158
|
+
form[key] = options[key];
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
function ondata(name, val, data){
|
|
162
|
+
if (Array.isArray(data[name])) {
|
|
163
|
+
data[name].push(val);
|
|
164
|
+
} else if (data[name]) {
|
|
165
|
+
data[name] = [data[name], val];
|
|
166
|
+
} else {
|
|
167
|
+
data[name] = val;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
form.on('field', function(name, val){
|
|
172
|
+
ondata(name, val, data);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
form.on('file', function(name, val){
|
|
176
|
+
ondata(name, val, files);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
form.on('error', function(err){
|
|
180
|
+
fn(err);
|
|
181
|
+
done = true;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
form.on('end', function(){
|
|
185
|
+
if (done) return;
|
|
186
|
+
try {
|
|
187
|
+
req.body = qs.parse(data);
|
|
188
|
+
req.files = qs.parse(files);
|
|
189
|
+
fn();
|
|
190
|
+
} catch (err) {
|
|
191
|
+
fn(err);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
form.parse(req);
|
|
92
196
|
};
|
|
@@ -43,7 +43,11 @@ module.exports = function limit(bytes){
|
|
|
43
43
|
req._limit = true;
|
|
44
44
|
|
|
45
45
|
// limit by content-length
|
|
46
|
-
if (len && len > bytes)
|
|
46
|
+
if (len && len > bytes) {
|
|
47
|
+
res.statusCode = 413;
|
|
48
|
+
res.end('Request Entity Too Large');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
47
51
|
|
|
48
52
|
// limit
|
|
49
53
|
req.on('data', function(chunk){
|
|
@@ -55,10 +55,10 @@ function defaultFingerprint(req) {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* Paths to ignore
|
|
58
|
+
* Paths to ignore.
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
|
-
exports.ignore = [
|
|
61
|
+
exports.ignore = [];
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Setup session store with the given `options`.
|
|
@@ -39,6 +39,7 @@ var fs = require('fs')
|
|
|
39
39
|
*
|
|
40
40
|
* - `maxAge` Browser cache maxAge in milliseconds. defaults to 0
|
|
41
41
|
* - `hidden` Allow transfer of hidden files. defaults to false
|
|
42
|
+
* - `redirect` Redirect to trailing "/" when the pathname is a dir
|
|
42
43
|
*
|
|
43
44
|
* @param {String} root
|
|
44
45
|
* @param {Object} options
|
|
@@ -101,6 +102,7 @@ var send = exports.send = function(req, res, next, options){
|
|
|
101
102
|
, head = 'HEAD' == req.method
|
|
102
103
|
, get = 'GET' == req.method
|
|
103
104
|
, root = options.root ? normalize(options.root) : null
|
|
105
|
+
, redirect = false === options.redirect ? false : true
|
|
104
106
|
, getOnly = options.getOnly
|
|
105
107
|
, fn = options.callback
|
|
106
108
|
, hidden = options.hidden
|
|
@@ -132,7 +134,7 @@ var send = exports.send = function(req, res, next, options){
|
|
|
132
134
|
: utils.forbidden(res);
|
|
133
135
|
|
|
134
136
|
// index.html support
|
|
135
|
-
if ('/' == path[path.length - 1]) path += 'index.html';
|
|
137
|
+
if (normalize('/') == path[path.length - 1]) path += 'index.html';
|
|
136
138
|
|
|
137
139
|
// "hidden" file
|
|
138
140
|
if (!hidden && '.' == basename(path)[0]) return next();
|
|
@@ -149,13 +151,34 @@ var send = exports.send = function(req, res, next, options){
|
|
|
149
151
|
: next(err);
|
|
150
152
|
// redirect directory in case index.html is present
|
|
151
153
|
} else if (stat.isDirectory()) {
|
|
154
|
+
if (!redirect) return next();
|
|
152
155
|
res.statusCode = 301;
|
|
153
156
|
res.setHeader('Location', url.pathname + '/');
|
|
154
157
|
res.end('Redirecting to ' + url.pathname + '/');
|
|
155
158
|
return;
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
// header fields
|
|
162
|
+
if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString());
|
|
163
|
+
if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000));
|
|
164
|
+
if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString());
|
|
165
|
+
if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat));
|
|
166
|
+
if (!res.getHeader('content-type')) {
|
|
167
|
+
var charset = mime.charsets.lookup(type);
|
|
168
|
+
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
|
|
169
|
+
}
|
|
170
|
+
res.setHeader('Accept-Ranges', 'bytes');
|
|
171
|
+
|
|
172
|
+
// conditional GET support
|
|
173
|
+
if (utils.conditionalGET(req)) {
|
|
174
|
+
if (!utils.modified(req, res)) {
|
|
175
|
+
req.emit('static');
|
|
176
|
+
return utils.notModified(res);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
158
180
|
var opts = {};
|
|
181
|
+
var chunkSize = stat.size;
|
|
159
182
|
|
|
160
183
|
// we have a Range request
|
|
161
184
|
if (ranges) {
|
|
@@ -166,6 +189,7 @@ var send = exports.send = function(req, res, next, options){
|
|
|
166
189
|
// TODO: multiple support
|
|
167
190
|
opts.start = ranges[0].start;
|
|
168
191
|
opts.end = ranges[0].end;
|
|
192
|
+
chunkSize = opts.end - opts.start + 1;
|
|
169
193
|
res.statusCode = 206;
|
|
170
194
|
res.setHeader('Content-Range', 'bytes '
|
|
171
195
|
+ opts.start
|
|
@@ -179,27 +203,9 @@ var send = exports.send = function(req, res, next, options){
|
|
|
179
203
|
? fn(new Error('Requested Range Not Satisfiable'))
|
|
180
204
|
: invalidRange(res);
|
|
181
205
|
}
|
|
182
|
-
// stream the entire file
|
|
183
|
-
} else {
|
|
184
|
-
res.setHeader('Content-Length', stat.size);
|
|
185
|
-
if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000));
|
|
186
|
-
if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString());
|
|
187
|
-
if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat));
|
|
188
|
-
|
|
189
|
-
// conditional GET support
|
|
190
|
-
if (utils.conditionalGET(req)) {
|
|
191
|
-
if (!utils.modified(req, res)) {
|
|
192
|
-
return utils.notModified(res);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
206
|
}
|
|
196
207
|
|
|
197
|
-
|
|
198
|
-
if (!res.getHeader('content-type')) {
|
|
199
|
-
var charset = mime.charsets.lookup(type);
|
|
200
|
-
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
|
|
201
|
-
}
|
|
202
|
-
res.setHeader('Accept-Ranges', 'bytes');
|
|
208
|
+
res.setHeader('Content-Length', chunkSize);
|
|
203
209
|
|
|
204
210
|
// transfer
|
|
205
211
|
if (head) return res.end();
|
|
@@ -213,7 +219,6 @@ var send = exports.send = function(req, res, next, options){
|
|
|
213
219
|
if (fn) {
|
|
214
220
|
function callback(err) { done || fn(err); done = true }
|
|
215
221
|
req.on('close', callback);
|
|
216
|
-
req.socket.on('error', callback);
|
|
217
222
|
stream.on('end', callback);
|
|
218
223
|
}
|
|
219
224
|
});
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
var http = require('http')
|
|
13
|
+
, utils = require('../utils')
|
|
13
14
|
, Cache = require('../cache')
|
|
14
15
|
, url = require('url')
|
|
15
16
|
, fs = require('fs');
|
|
@@ -33,17 +34,15 @@ var http = require('http')
|
|
|
33
34
|
*
|
|
34
35
|
* Benchmarks:
|
|
35
36
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* static(): 2700 rps
|
|
38
|
+
* node-static: 5300 rps
|
|
39
|
+
* static() + staticCache(): 7500 rps
|
|
39
40
|
*
|
|
40
41
|
* Options:
|
|
41
42
|
*
|
|
42
43
|
* - `maxObjects` max cache objects [128]
|
|
43
44
|
* - `maxLength` max cache object length 256kb
|
|
44
45
|
*
|
|
45
|
-
* TODO: refactore to accept data stores (redis etc)
|
|
46
|
-
*
|
|
47
46
|
* @param {Type} name
|
|
48
47
|
* @return {Type}
|
|
49
48
|
* @api public
|
|
@@ -56,16 +55,82 @@ module.exports = function staticCache(options){
|
|
|
56
55
|
|
|
57
56
|
return function staticCache(req, res, next){
|
|
58
57
|
var path = url.parse(req.url).pathname
|
|
58
|
+
, ranges = req.headers.range
|
|
59
59
|
, hit = cache.get(path)
|
|
60
|
-
,
|
|
61
|
-
,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
, hitCC
|
|
61
|
+
, uaCC
|
|
62
|
+
, header
|
|
63
|
+
, age;
|
|
64
|
+
|
|
65
|
+
// cache static
|
|
66
|
+
req.on('static', function(stream){
|
|
67
|
+
var headers = res._headers
|
|
68
|
+
, cc = utils.parseCacheControl(headers['cache-control'] || '')
|
|
69
|
+
, contentLength = headers['content-length']
|
|
70
|
+
, hit;
|
|
71
|
+
|
|
72
|
+
// ignore larger files
|
|
73
|
+
if (!contentLength || contentLength > maxlen) return;
|
|
74
|
+
|
|
75
|
+
// dont cache items we shouldn't be
|
|
76
|
+
if ( cc['no-cache']
|
|
77
|
+
|| cc['no-store']
|
|
78
|
+
|| cc['private']
|
|
79
|
+
|| cc['must-revalidate']) return;
|
|
80
|
+
|
|
81
|
+
// if already in cache then validate
|
|
82
|
+
if (hit = cache.get(path)){
|
|
83
|
+
if (headers.etag == hit[0].etag) {
|
|
84
|
+
hit[0].date = new Date;
|
|
85
|
+
return;
|
|
86
|
+
} else {
|
|
87
|
+
cache.remove(path);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// validation notifiactions don't contain a steam
|
|
92
|
+
if (null == stream) return;
|
|
93
|
+
|
|
94
|
+
// add the cache object
|
|
95
|
+
var arr = cache.add(path);
|
|
96
|
+
arr.push(headers);
|
|
97
|
+
|
|
98
|
+
// store the chunks
|
|
99
|
+
stream.on('data', function(chunk){
|
|
100
|
+
arr.push(chunk);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// flag it as complete
|
|
104
|
+
stream.on('end', function(){
|
|
105
|
+
arr.complete = true;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// cache hit, doesnt support range requests
|
|
110
|
+
if (hit && hit.complete && !ranges) {
|
|
111
|
+
header = utils.merge({}, hit[0]);
|
|
112
|
+
header.Age = age = (new Date - new Date(header.date)) / 1000 | 0;
|
|
113
|
+
header.date = new Date().toUTCString();
|
|
114
|
+
|
|
115
|
+
// parse cache-controls
|
|
116
|
+
hitCC = utils.parseCacheControl(header['cache-control'] || '');
|
|
117
|
+
uaCC = utils.parseCacheControl(req.headers['cache-control'] || '');
|
|
118
|
+
|
|
119
|
+
// check if we must revalidate(bypass)
|
|
120
|
+
if (hitCC['no-cache'] || uaCC['no-cache']) return next();
|
|
121
|
+
|
|
122
|
+
// check freshness of entity
|
|
123
|
+
if (isStale(hitCC, age) || isStale(uaCC, age)) return next();
|
|
124
|
+
|
|
125
|
+
// conditional GET support
|
|
126
|
+
if (utils.conditionalGET(req)) {
|
|
127
|
+
if (!utils.modified(req, res, header)) {
|
|
128
|
+
header['content-length'] = 0;
|
|
129
|
+
res.writeHead(304, header);
|
|
130
|
+
return res.end();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
69
134
|
// HEAD support
|
|
70
135
|
if ('HEAD' == req.method) {
|
|
71
136
|
header['content-length'] = 0;
|
|
@@ -92,31 +157,19 @@ module.exports = function staticCache(options){
|
|
|
92
157
|
return write(1);
|
|
93
158
|
}
|
|
94
159
|
|
|
95
|
-
// cache static
|
|
96
|
-
req.on('static', function(stream){
|
|
97
|
-
// ignore larger files
|
|
98
|
-
var contentLength = res._headers['content-length'];
|
|
99
|
-
if (!contentLength || contentLength > maxlen) return;
|
|
100
|
-
|
|
101
|
-
// exists
|
|
102
|
-
if (cache.get(path)) return;
|
|
103
|
-
|
|
104
|
-
// add the cache object
|
|
105
|
-
var arr = cache.add(path);
|
|
106
|
-
arr.push(res._headers);
|
|
107
|
-
|
|
108
|
-
// store the chunks
|
|
109
|
-
stream.on('data', function(chunk){
|
|
110
|
-
arr.push(chunk);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// flag it as complete
|
|
114
|
-
stream.on('end', function(){
|
|
115
|
-
arr.complete = true;
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
160
|
next();
|
|
120
161
|
}
|
|
121
162
|
};
|
|
122
163
|
|
|
164
|
+
/**
|
|
165
|
+
* Check if cache item is stale
|
|
166
|
+
*
|
|
167
|
+
* @param {Object} cc
|
|
168
|
+
* @param {Number} age
|
|
169
|
+
* @return {Boolean}
|
|
170
|
+
* @api private
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
function isStale(cc, age) {
|
|
174
|
+
return cc['max-age'] && cc['max-age'] <= age;
|
|
175
|
+
}
|
|
@@ -36,7 +36,7 @@ module.exports = function vhost(hostname, server){
|
|
|
36
36
|
var host = req.headers.host.split(':')[0];
|
|
37
37
|
if (req.subdomains = regexp.exec(host)) {
|
|
38
38
|
req.subdomains = req.subdomains[0].split('.').slice(0, -1);
|
|
39
|
-
server.emit("request", req, res
|
|
39
|
+
server.emit("request", req, res);
|
|
40
40
|
} else {
|
|
41
41
|
next();
|
|
42
42
|
}
|
|
@@ -403,14 +403,21 @@ exports.parseRange = function(size, str){
|
|
|
403
403
|
*/
|
|
404
404
|
|
|
405
405
|
exports.parseCacheControl = function(str){
|
|
406
|
-
var
|
|
407
|
-
, key = parts.shift()
|
|
408
|
-
, val = parseInt(parts.shift(), 10)
|
|
406
|
+
var directives = str.split(',')
|
|
409
407
|
, obj = {};
|
|
410
|
-
|
|
408
|
+
|
|
409
|
+
for(var i = 0, len = directives.length; i < len; i++) {
|
|
410
|
+
var parts = directives[i].split('=')
|
|
411
|
+
, key = parts.shift().trim()
|
|
412
|
+
, val = parseInt(parts.shift(), 10);
|
|
413
|
+
|
|
414
|
+
obj[key] = isNaN(val) ? true : val;
|
|
415
|
+
}
|
|
416
|
+
|
|
411
417
|
return obj;
|
|
412
418
|
};
|
|
413
419
|
|
|
420
|
+
|
|
414
421
|
/**
|
|
415
422
|
* Convert array-like object to an `Array`.
|
|
416
423
|
*
|