vulcan 0.1.6 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/lib/vulcan/cli.rb +3 -0
  2. data/lib/vulcan/version.rb +1 -1
  3. data/server/lib/spawner.js +9 -4
  4. data/server/node_modules/cradle/lib/cradle.js +0 -1
  5. data/server/node_modules/cradle/package.json +3 -3
  6. data/server/node_modules/cradle/test/cache-test.js +6 -7
  7. data/server/node_modules/cradle/test/cradle-test.js +4 -5
  8. data/server/node_modules/cradle/test/response-test.js +5 -6
  9. data/server/node_modules/express/History.md +40 -0
  10. data/server/node_modules/express/Makefile +3 -9
  11. data/server/node_modules/express/Readme.md +3 -1
  12. data/server/node_modules/express/bin/express +61 -63
  13. data/server/node_modules/express/lib/express.js +1 -1
  14. data/server/node_modules/express/lib/request.js +9 -7
  15. data/server/node_modules/express/lib/view.js +19 -16
  16. data/server/node_modules/express/node_modules/connect/lib/connect.js +1 -1
  17. data/server/node_modules/express/node_modules/connect/lib/http.js +2 -0
  18. data/server/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js +135 -31
  19. data/server/node_modules/express/node_modules/connect/lib/middleware/limit.js +5 -1
  20. data/server/node_modules/express/node_modules/connect/lib/middleware/session.js +2 -2
  21. data/server/node_modules/express/node_modules/connect/lib/middleware/static.js +26 -21
  22. data/server/node_modules/express/node_modules/connect/lib/middleware/staticCache.js +91 -38
  23. data/server/node_modules/express/node_modules/connect/lib/middleware/vhost.js +1 -1
  24. data/server/node_modules/express/node_modules/connect/lib/utils.js +11 -4
  25. data/server/node_modules/express/node_modules/connect/node_modules/formidable/Makefile +14 -0
  26. data/server/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md +286 -0
  27. data/server/node_modules/express/node_modules/connect/node_modules/formidable/TODO +3 -0
  28. data/server/node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js +70 -0
  29. data/server/node_modules/express/node_modules/connect/node_modules/formidable/example/post.js +43 -0
  30. data/server/node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js +48 -0
  31. data/server/node_modules/express/node_modules/connect/node_modules/formidable/index.js +1 -0
  32. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js +61 -0
  33. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js +377 -0
  34. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js +3 -0
  35. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js +312 -0
  36. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js +25 -0
  37. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/util.js +6 -0
  38. data/server/node_modules/express/node_modules/connect/node_modules/formidable/package.json +22 -0
  39. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/common.js +19 -0
  40. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt +1 -0
  41. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt +1 -0
  42. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/no-filename/generic.http +13 -0
  43. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md +3 -0
  44. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +26 -0
  45. 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
  46. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +23 -0
  47. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +24 -0
  48. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +22 -0
  49. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +22 -0
  50. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +22 -0
  51. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js +3 -0
  52. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +21 -0
  53. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multi_video.upload +0 -0
  54. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js +72 -0
  55. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js +89 -0
  56. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js +24 -0
  57. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js +80 -0
  58. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js +104 -0
  59. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +715 -0
  60. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js +50 -0
  61. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js +45 -0
  62. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js +72 -0
  63. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/run.js +2 -0
  64. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js +63 -0
  65. data/server/node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js +47 -0
  66. data/server/node_modules/express/node_modules/connect/package.json +7 -6
  67. data/server/node_modules/express/node_modules/connect/test.js +44 -31
  68. data/server/node_modules/express/node_modules/qs/History.md +11 -0
  69. data/server/node_modules/express/node_modules/qs/Makefile +1 -3
  70. data/server/node_modules/express/node_modules/qs/Readme.md +2 -4
  71. data/server/node_modules/express/node_modules/qs/lib/querystring.js +100 -74
  72. data/server/node_modules/express/node_modules/qs/package.json +9 -2
  73. data/server/node_modules/express/node_modules/qs/test/mocha.opts +2 -0
  74. data/server/node_modules/express/node_modules/qs/test/{parse.test.js → parse.js} +1 -2
  75. data/server/node_modules/express/node_modules/qs/test/{stringify.test.js → stringify.js} +0 -0
  76. data/server/node_modules/express/package.json +7 -7
  77. data/server/node_modules/express/testing/foo/app.js +35 -0
  78. data/server/node_modules/express/testing/foo/package.json +9 -0
  79. data/server/node_modules/express/testing/foo/public/stylesheets/style.css +8 -0
  80. data/server/node_modules/express/testing/foo/routes/index.js +10 -0
  81. data/server/node_modules/express/testing/foo/views/index.jade +2 -0
  82. data/server/node_modules/express/testing/foo/views/layout.jade +6 -0
  83. data/server/node_modules/express/testing/index.js +31 -5
  84. data/server/node_modules/express/testing/public/test.txt +2971 -0
  85. data/server/node_modules/express/testing/views/page.html +1 -0
  86. data/server/node_modules/express/testing/views/page.jade +3 -0
  87. data/server/node_modules/express/testing/views/test.md +1 -0
  88. data/server/node_modules/express/testing/views/user/index.jade +1 -0
  89. data/server/node_modules/express/testing/views/user/list.jade +1 -0
  90. data/server/node_modules/node-uuid/README.md +166 -67
  91. data/server/node_modules/node-uuid/benchmark/README.md +53 -0
  92. data/server/node_modules/node-uuid/benchmark/bench.gnu +174 -0
  93. data/server/node_modules/node-uuid/benchmark/bench.sh +34 -0
  94. data/server/node_modules/node-uuid/{test → benchmark}/benchmark-native.c +0 -0
  95. data/server/node_modules/node-uuid/benchmark/benchmark.js +84 -0
  96. data/server/node_modules/node-uuid/package.json +5 -3
  97. data/server/node_modules/node-uuid/test/benchmark-native +0 -0
  98. data/server/node_modules/node-uuid/test/compare_v1.js +63 -0
  99. data/server/node_modules/node-uuid/test/test.html +3 -0
  100. data/server/node_modules/node-uuid/test/test.js +214 -57
  101. data/server/node_modules/node-uuid/uuid.js +225 -56
  102. data/server/node_modules/restler/README.md +20 -7
  103. data/server/node_modules/restler/bin/restler +1 -1
  104. data/server/node_modules/restler/lib/multipartform.js +9 -8
  105. data/server/node_modules/restler/lib/restler.js +64 -22
  106. data/server/node_modules/restler/package.json +2 -2
  107. data/server/node_modules/restler/test/restler.js +22 -2
  108. data/server/node_modules/restler/test/test_helper.js +20 -1
  109. data/server/package.json +8 -8
  110. data/server/web.js +22 -6
  111. metadata +72 -82
  112. data/server/node_modules/cradle/node_modules/vows/LICENSE +0 -20
  113. data/server/node_modules/cradle/node_modules/vows/Makefile +0 -7
  114. data/server/node_modules/cradle/node_modules/vows/README.md +0 -39
  115. data/server/node_modules/cradle/node_modules/vows/bin/vows +0 -515
  116. data/server/node_modules/cradle/node_modules/vows/lib/assert/error.js +0 -27
  117. data/server/node_modules/cradle/node_modules/vows/lib/assert/macros.js +0 -215
  118. data/server/node_modules/cradle/node_modules/vows/lib/assert/utils.js +0 -77
  119. data/server/node_modules/cradle/node_modules/vows/lib/vows.js +0 -193
  120. data/server/node_modules/cradle/node_modules/vows/lib/vows/console.js +0 -131
  121. data/server/node_modules/cradle/node_modules/vows/lib/vows/context.js +0 -55
  122. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/file.js +0 -29
  123. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/fragments/coverage-foot.html +0 -2
  124. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/fragments/coverage-head.html +0 -61
  125. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-html.js +0 -54
  126. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-json.js +0 -54
  127. data/server/node_modules/cradle/node_modules/vows/lib/vows/coverage/report-plain.js +0 -38
  128. data/server/node_modules/cradle/node_modules/vows/lib/vows/extras.js +0 -28
  129. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/dot-matrix.js +0 -67
  130. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/json.js +0 -16
  131. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/silent.js +0 -8
  132. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/spec.js +0 -44
  133. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/watch.js +0 -39
  134. data/server/node_modules/cradle/node_modules/vows/lib/vows/reporters/xunit.js +0 -90
  135. data/server/node_modules/cradle/node_modules/vows/lib/vows/suite.js +0 -319
  136. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/LICENSE +0 -20
  137. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/Makefile +0 -4
  138. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/README.md +0 -72
  139. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/lib/eyes.js +0 -233
  140. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/package.json +0 -14
  141. data/server/node_modules/cradle/node_modules/vows/node_modules/eyes/test/eyes-test.js +0 -55
  142. data/server/node_modules/cradle/node_modules/vows/package.json +0 -14
  143. data/server/node_modules/cradle/node_modules/vows/test/assert-test.js +0 -135
  144. data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/failing.js +0 -18
  145. data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/log.js +0 -18
  146. data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/passing.js +0 -17
  147. data/server/node_modules/cradle/node_modules/vows/test/fixtures/isolate/stderr.js +0 -18
  148. data/server/node_modules/cradle/node_modules/vows/test/isolate-test.js +0 -140
  149. data/server/node_modules/cradle/node_modules/vows/test/testInherit.js +0 -133
  150. data/server/node_modules/cradle/node_modules/vows/test/vows-error-test.js +0 -51
  151. data/server/node_modules/cradle/node_modules/vows/test/vows-test.js +0 -374
  152. data/server/node_modules/express/node_modules/qs/support/expresso/History.md +0 -128
  153. data/server/node_modules/express/node_modules/qs/support/expresso/Makefile +0 -53
  154. data/server/node_modules/express/node_modules/qs/support/expresso/Readme.md +0 -61
  155. data/server/node_modules/express/node_modules/qs/support/expresso/bin/expresso +0 -856
  156. data/server/node_modules/express/node_modules/qs/support/expresso/docs/api.html +0 -1080
  157. data/server/node_modules/express/node_modules/qs/support/expresso/docs/index.html +0 -377
  158. data/server/node_modules/express/node_modules/qs/support/expresso/docs/index.md +0 -290
  159. data/server/node_modules/express/node_modules/qs/support/expresso/docs/layout/foot.html +0 -3
  160. data/server/node_modules/express/node_modules/qs/support/expresso/docs/layout/head.html +0 -42
  161. data/server/node_modules/express/node_modules/qs/support/expresso/lib/bar.js +0 -4
  162. data/server/node_modules/express/node_modules/qs/support/expresso/lib/foo.js +0 -16
  163. data/server/node_modules/express/node_modules/qs/support/expresso/package.json +0 -12
  164. data/server/node_modules/express/node_modules/qs/support/expresso/test/assert.test.js +0 -91
  165. data/server/node_modules/express/node_modules/qs/support/expresso/test/async.test.js +0 -12
  166. data/server/node_modules/express/node_modules/qs/support/expresso/test/bar.test.js +0 -13
  167. data/server/node_modules/express/node_modules/qs/support/expresso/test/foo.test.js +0 -14
  168. data/server/node_modules/express/node_modules/qs/support/expresso/test/http.test.js +0 -146
  169. data/server/node_modules/express/node_modules/qs/support/expresso/test/serial/async.test.js +0 -39
  170. data/server/node_modules/express/node_modules/qs/support/expresso/test/serial/http.test.js +0 -48
  171. data/server/node_modules/express/node_modules/qs/support/should/History.md +0 -22
  172. data/server/node_modules/express/node_modules/qs/support/should/Makefile +0 -6
  173. data/server/node_modules/express/node_modules/qs/support/should/Readme.md +0 -248
  174. data/server/node_modules/express/node_modules/qs/support/should/examples/runner.js +0 -53
  175. data/server/node_modules/express/node_modules/qs/support/should/index.js +0 -2
  176. data/server/node_modules/express/node_modules/qs/support/should/lib/eql.js +0 -91
  177. data/server/node_modules/express/node_modules/qs/support/should/lib/should.js +0 -548
  178. data/server/node_modules/express/node_modules/qs/support/should/package.json +0 -8
  179. data/server/node_modules/express/node_modules/qs/support/should/test/should.test.js +0 -358
  180. data/server/node_modules/express/testing/views/users.jade +0 -1
  181. data/server/node_modules/node-uuid/test/benchmark.js +0 -27
@@ -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
- * static(): 2700 rps
37
- * node-static: 5300 rps
38
- * static() + staticCache(): 7500 rps
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
- , cc = req.headers['cache-control']
61
- , header;
62
-
63
- // cache hit
64
- if (hit && hit.complete) {
65
- // TODO: finish meeee... http caching... throttling etc
66
- header = hit[0];
67
- header.Age = (new Date - hit.createdAt) / 1000 | 0;
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, next);
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 parts = str.split('=')
407
- , key = parts.shift()
408
- , val = parseInt(parts.shift(), 10)
406
+ var directives = str.split(',')
409
407
  , obj = {};
410
- obj[key] = isNaN(val) ? true : val;
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
  *
@@ -0,0 +1,14 @@
1
+ SHELL := /bin/bash
2
+
3
+ test:
4
+ @./test/run.js
5
+
6
+ build: npm test
7
+
8
+ npm:
9
+ npm install .
10
+
11
+ clean:
12
+ rm test/tmp/*
13
+
14
+ .PHONY: test clean build
@@ -0,0 +1,286 @@
1
+ # Formidable
2
+
3
+ [![Build Status](https://secure.travis-ci.org/felixge/node-formidable.png)](http://travis-ci.org/felixge/node-formidable)
4
+
5
+ ## Purpose
6
+
7
+ A node.js module for parsing form data, especially file uploads.
8
+
9
+ ## Current status
10
+
11
+ This module was developed for [Transloadit](http://transloadit.com/), a service focused on uploading
12
+ and encoding images and videos. It has been battle-tested against hundreds of GB of file uploads from
13
+ a large variety of clients and is considered production-ready.
14
+
15
+ ## Features
16
+
17
+ * Fast (~500mb/sec), non-buffering multipart parser
18
+ * Automatically writing file uploads to disk
19
+ * Low memory footprint
20
+ * Graceful error handling
21
+ * Very high test coverage
22
+
23
+ ## Changelog
24
+
25
+ ### v1.0.6
26
+
27
+ * Do not default to the default to the field name for file uploads where
28
+ filename="".
29
+
30
+ ### v1.0.5
31
+
32
+ * Support filename="" in multipart parts
33
+ * Explain unexpected end() errors in parser better
34
+
35
+ **Note:** Starting with this version, formidable emits 'file' events for empty
36
+ file input fields. Previously those were incorrectly emitted as regular file
37
+ input fields with value = "".
38
+
39
+ ### v1.0.4
40
+
41
+ * Detect a good default tmp directory regardless of platform. (#88)
42
+
43
+ ### v1.0.3
44
+
45
+ * Fix problems with utf8 characters (#84) / semicolons in filenames (#58)
46
+ * Small performance improvements
47
+ * New test suite and fixture system
48
+
49
+ ### v1.0.2
50
+
51
+ * Exclude node\_modules folder from git
52
+ * Implement new `'aborted'` event
53
+ * Fix files in example folder to work with recent node versions
54
+ * Make gently a devDependency
55
+
56
+ [See Commits](https://github.com/felixge/node-formidable/compare/v1.0.1...v1.0.2)
57
+
58
+ ### v1.0.1
59
+
60
+ * Fix package.json to refer to proper main directory. (#68, Dean Landolt)
61
+
62
+ [See Commits](https://github.com/felixge/node-formidable/compare/v1.0.0...v1.0.1)
63
+
64
+ ### v1.0.0
65
+
66
+ * Add support for multipart boundaries that are quoted strings. (Jeff Craig)
67
+
68
+ This marks the beginning of development on version 2.0 which will include
69
+ several architectural improvements.
70
+
71
+ [See Commits](https://github.com/felixge/node-formidable/compare/v0.9.11...v1.0.0)
72
+
73
+ ### v0.9.11
74
+
75
+ * Emit `'progress'` event when receiving data, regardless of parsing it. (Tim Koschützki)
76
+ * Use [W3C FileAPI Draft](http://dev.w3.org/2006/webapi/FileAPI/) properties for File class
77
+
78
+ **Important:** The old property names of the File class will be removed in a
79
+ future release.
80
+
81
+ [See Commits](https://github.com/felixge/node-formidable/compare/v0.9.10...v0.9.11)
82
+
83
+ ### Older releases
84
+
85
+ These releases were done before starting to maintain the above Changelog:
86
+
87
+ * [v0.9.10](https://github.com/felixge/node-formidable/compare/v0.9.9...v0.9.10)
88
+ * [v0.9.9](https://github.com/felixge/node-formidable/compare/v0.9.8...v0.9.9)
89
+ * [v0.9.8](https://github.com/felixge/node-formidable/compare/v0.9.7...v0.9.8)
90
+ * [v0.9.7](https://github.com/felixge/node-formidable/compare/v0.9.6...v0.9.7)
91
+ * [v0.9.6](https://github.com/felixge/node-formidable/compare/v0.9.5...v0.9.6)
92
+ * [v0.9.5](https://github.com/felixge/node-formidable/compare/v0.9.4...v0.9.5)
93
+ * [v0.9.4](https://github.com/felixge/node-formidable/compare/v0.9.3...v0.9.4)
94
+ * [v0.9.3](https://github.com/felixge/node-formidable/compare/v0.9.2...v0.9.3)
95
+ * [v0.9.2](https://github.com/felixge/node-formidable/compare/v0.9.1...v0.9.2)
96
+ * [v0.9.1](https://github.com/felixge/node-formidable/compare/v0.9.0...v0.9.1)
97
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
98
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
99
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
100
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
101
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
102
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
103
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
104
+ * [v0.9.0](https://github.com/felixge/node-formidable/compare/v0.8.0...v0.9.0)
105
+ * [v0.1.0](https://github.com/felixge/node-formidable/commits/v0.1.0)
106
+
107
+ ## Installation
108
+
109
+ Via [npm](http://github.com/isaacs/npm):
110
+
111
+ npm install formidable@latest
112
+
113
+ Manually:
114
+
115
+ git clone git://github.com/felixge/node-formidable.git formidable
116
+ vim my.js
117
+ # var formidable = require('./formidable');
118
+
119
+ Note: Formidable requires [gently](http://github.com/felixge/node-gently) to run the unit tests, but you won't need it for just using the library.
120
+
121
+ ## Example
122
+
123
+ Parse an incoming file upload.
124
+
125
+ var formidable = require('formidable'),
126
+ http = require('http'),
127
+
128
+ sys = require('sys');
129
+
130
+ http.createServer(function(req, res) {
131
+ if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
132
+ // parse a file upload
133
+ var form = new formidable.IncomingForm();
134
+ form.parse(req, function(err, fields, files) {
135
+ res.writeHead(200, {'content-type': 'text/plain'});
136
+ res.write('received upload:\n\n');
137
+ res.end(sys.inspect({fields: fields, files: files}));
138
+ });
139
+ return;
140
+ }
141
+
142
+ // show a file upload form
143
+ res.writeHead(200, {'content-type': 'text/html'});
144
+ res.end(
145
+ '<form action="/upload" enctype="multipart/form-data" method="post">'+
146
+ '<input type="text" name="title"><br>'+
147
+ '<input type="file" name="upload" multiple="multiple"><br>'+
148
+ '<input type="submit" value="Upload">'+
149
+ '</form>'
150
+ );
151
+ }).listen(80);
152
+
153
+ ## API
154
+
155
+ ### formidable.IncomingForm
156
+
157
+ #### new formidable.IncomingForm()
158
+
159
+ Creates a new incoming form.
160
+
161
+ #### incomingForm.encoding = 'utf-8'
162
+
163
+ The encoding to use for incoming form fields.
164
+
165
+ #### incomingForm.uploadDir = process.env.TMP || '/tmp' || process.cwd()
166
+
167
+ The directory for placing file uploads in. You can move them later on using
168
+ `fs.rename()`. The default directory is picked at module load time depending on
169
+ the first existing directory from those listed above.
170
+
171
+ #### incomingForm.keepExtensions = false
172
+
173
+ If you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`.
174
+
175
+ #### incomingForm.type
176
+
177
+ Either 'multipart' or 'urlencoded' depending on the incoming request.
178
+
179
+ #### incomingForm.maxFieldsSize = 2 * 1024 * 1024
180
+
181
+ Limits the amount of memory a field (not file) can allocate in bytes.
182
+ If this value is exceeded, an `'error'` event is emitted. The default
183
+ size is 2MB.
184
+
185
+ #### incomingForm.bytesReceived
186
+
187
+ The amount of bytes received for this form so far.
188
+
189
+ #### incomingForm.bytesExpected
190
+
191
+ The expected number of bytes in this form.
192
+
193
+ #### incomingForm.parse(request, [cb])
194
+
195
+ Parses an incoming node.js `request` containing form data. If `cb` is provided, all fields an files are collected and passed to the callback:
196
+
197
+ incomingForm.parse(req, function(err, fields, files) {
198
+ // ...
199
+ });
200
+
201
+ #### incomingForm.onPart(part)
202
+
203
+ You may overwrite this method if you are interested in directly accessing the multipart stream. Doing so will disable any `'field'` / `'file'` events processing which would occur otherwise, making you fully responsible for handling the processing.
204
+
205
+ incomingForm.onPart = function(part) {
206
+ part.addListener('data', function() {
207
+ // ...
208
+ });
209
+ }
210
+
211
+ If you want to use formidable to only handle certain parts for you, you can do so:
212
+
213
+ incomingForm.onPart = function(part) {
214
+ if (!part.filename) {
215
+ // let formidable handle all non-file parts
216
+ incomingForm.handlePart(part);
217
+ }
218
+ }
219
+
220
+ Check the code in this method for further inspiration.
221
+
222
+ #### Event: 'progress' (bytesReceived, bytesExpected)
223
+
224
+ Emitted after each incoming chunk of data that has been parsed. Can be used to roll your own progress bar.
225
+
226
+ #### Event: 'field' (name, value)
227
+
228
+ Emitted whenever a field / value pair has been received.
229
+
230
+ #### Event: 'fileBegin' (name, file)
231
+
232
+ Emitted whenever a new file is detected in the upload stream. Use this even if
233
+ you want to stream the file to somewhere else while buffering the upload on
234
+ the file system.
235
+
236
+ #### Event: 'file' (name, file)
237
+
238
+ Emitted whenever a field / file pair has been received. `file` is an instance of `File`.
239
+
240
+ #### Event: 'error' (err)
241
+
242
+ Emitted when there is an error processing the incoming form. A request that experiences an error is automatically paused, you will have to manually call `request.resume()` if you want the request to continue firing `'data'` events.
243
+
244
+ #### Event: 'aborted'
245
+
246
+ Emitted when the request was aborted by the user. Right now this can be due to a 'timeout' or 'close' event on the socket. In the future there will be a separate 'timeout' event (needs a change in the node core).
247
+
248
+ #### Event: 'end' ()
249
+
250
+ Emitted when the entire request has been received, and all contained files have finished flushing to disk. This is a great place for you to send your response.
251
+
252
+ ### formidable.File
253
+
254
+ #### file.size = 0
255
+
256
+ The size of the uploaded file in bytes. If the file is still being uploaded (see `'fileBegin'` event), this property says how many bytes of the file have been written to disk yet.
257
+
258
+ #### file.path = null
259
+
260
+ The path this file is being written to. You can modify this in the `'fileBegin'` event in
261
+ case you are unhappy with the way formidable generates a temporary path for your files.
262
+
263
+ #### file.name = null
264
+
265
+ The name this file had according to the uploading client.
266
+
267
+ #### file.type = null
268
+
269
+ The mime type of this file, according to the uploading client.
270
+
271
+ #### file.lastModifiedDate = null
272
+
273
+ A date object (or `null`) containing the time this file was last written to. Mostly
274
+ here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/).
275
+
276
+ ## License
277
+
278
+ Formidable is licensed under the MIT license.
279
+
280
+ ## Ports
281
+
282
+ * [multipart-parser](http://github.com/FooBarWidget/multipart-parser): a C++ parser based on formidable
283
+
284
+ ## Credits
285
+
286
+ * [Ryan Dahl](http://twitter.com/ryah) for his work on [http-parser](http://github.com/ry/http-parser) which heavily inspired multipart_parser.js