Skip to content
This repository
  • 2 commits
  • 4 files changed
  • 2 comments
  • 1 contributor
Jun 14, 2010
Felix Geisendörfer New feature: form.keepExtensions
This is useful if you process uploaded files using comannd line tools
that determine the type of a file using its extension. (I will hunt down
the authors of these tools so we won't have to rely on file extensions
any more in the future)
10c57f0
Felix Geisendörfer Bump version af57e61
4  Readme.md
Source Rendered
@@ -78,6 +78,10 @@ The encoding to use for incoming form fields.
78 78
 
79 79
 The directory for placing file uploads in. You can later on move them using `fs.rename()`.
80 80
 
  81
+#### incomingForm.keepExtensions = false
  82
+
  83
+If you want the files written to `incomingForm.uploadDir` to include the extensions of the original files, set this property to `true`.
  84
+
81 85
 #### incomingForm.type
82 86
 
83 87
 Either 'multipart' or 'urlencoded' depending on the incoming request.
9  lib/formidable/incoming_form.js
@@ -14,6 +14,7 @@ function IncomingForm() {
14 14
   this.error = null;
15 15
   this.ended = false;
16 16
 
  17
+  this.keepExtensions = false;
17 18
   this.uploadDir = '/tmp';
18 19
   this.encoding = 'utf-8';
19 20
   this.headers = null;
@@ -150,7 +151,7 @@ IncomingForm.prototype.handlePart = function(part) {
150 151
 
151 152
   this._flushing++;
152 153
 
153  
-  var file = new WriteStream(this._uploadPath());
  154
+  var file = new WriteStream(this._uploadPath(part.filename));
154 155
   part.addListener('data', function(buffer) {
155 156
     self.pause();
156 157
     file.write(buffer, function() {
@@ -308,12 +309,16 @@ IncomingForm.prototype._initUrlencoded = function() {
308 309
   this._parser = parser;
309 310
 };
310 311
 
311  
-IncomingForm.prototype._uploadPath = function() {
  312
+IncomingForm.prototype._uploadPath = function(filename) {
312 313
   var name = '';
313 314
   for (i = 0; i < 32; i++) {
314 315
     name += Math.floor(Math.random() * 16).toString(16);
315 316
   }
316 317
 
  318
+  if (this.keepExtensions) {
  319
+    name += path.extname(filename);
  320
+  }
  321
+
317 322
   return path.join(this.uploadDir, name);
318 323
 };
319 324
 
2  package.json
... ...
@@ -1,5 +1,5 @@
1 1
 { "name" : "formidable"
2  
-, "version": "0.8.0"
  2
+, "version": "0.9.0"
3 3
 , "dependencies": {"gently": ">=0.7.0"}
4 4
 , "directories" : { "lib" : "./lib/formidable" }
5 5
 , "main" : "./lib/formidable/index"
55  test/simple/test-incoming-form.js
@@ -26,6 +26,7 @@ test(function constructor() {
26 26
   assert.strictEqual(form.ended, false);
27 27
   assert.strictEqual(form.type, null);
28 28
   assert.strictEqual(form.headers, null);
  29
+  assert.strictEqual(form.keepExtensions, false);
29 30
   assert.strictEqual(form.uploadDir, '/tmp');
30 31
   assert.strictEqual(form.encoding, 'utf-8');
31 32
   assert.strictEqual(form.bytesReceived, null);
@@ -493,16 +494,20 @@ test(function handlePart() {
493 494
 
494 495
   (function testFilePart() {
495 496
     var PART = new events.EventEmitter()
496  
-      , FILE = new events.EventEmitter();
  497
+      , FILE = new events.EventEmitter()
  498
+      , PATH = '/foo/bar';
497 499
 
498 500
     PART.name = 'my_file';
499 501
     PART.filename = 'sweet.txt';
500 502
     PART.mime = 'sweet.txt';
501 503
 
502  
-    FILE.path = form._uploadPath();
  504
+    gently.expect(form, '_uploadPath', function(filename) {
  505
+      assert.equal(filename, PART.filename);
  506
+      return PATH;
  507
+    });
503 508
 
504  
-    gently.expect(WriteStreamStub, 'new', function(file) {
505  
-      assert.equal(path.dirname(file), form.uploadDir);
  509
+    gently.expect(WriteStreamStub, 'new', function(path) {
  510
+      assert.equal(path, PATH);
506 511
       FILE = this;
507 512
     });
508 513
 
@@ -543,19 +548,39 @@ test(function handlePart() {
543 548
 });
544 549
 
545 550
 test(function _uploadPath() {
546  
-  var UUID_A, UUID_B;
547  
-  gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
548  
-    assert.equal(uploadDir, form.uploadDir);
549  
-    UUID_A = uuid;
550  
-  });
551  
-  form._uploadPath();
  551
+  (function testUniqueId() {
  552
+    var UUID_A, UUID_B;
  553
+    gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
  554
+      assert.equal(uploadDir, form.uploadDir);
  555
+      UUID_A = uuid;
  556
+    });
  557
+    form._uploadPath();
552 558
 
553  
-  gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
554  
-    UUID_B = uuid;
555  
-  });
556  
-  form._uploadPath();
  559
+    gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, uuid) {
  560
+      UUID_B = uuid;
  561
+    });
  562
+    form._uploadPath();
  563
+
  564
+    assert.notEqual(UUID_A, UUID_B);
  565
+  })();
557 566
 
558  
-  assert.notEqual(UUID_A, UUID_B);
  567
+  (function testFileExtension() {
  568
+    form.keepExtensions = true;
  569
+    var FILENAME = 'foo.jpg'
  570
+      , EXT = '.bar';
  571
+
  572
+    gently.expect(GENTLY.hijacked.path, 'extname', function(filename) {
  573
+      assert.equal(filename, FILENAME);
  574
+      gently.restore(path, 'extname');
  575
+
  576
+      return EXT;
  577
+    });
  578
+
  579
+    gently.expect(GENTLY.hijacked.path, 'join', function(uploadDir, name) {
  580
+      assert.equal(path.extname(name), EXT);
  581
+    });
  582
+    form._uploadPath(FILENAME);
  583
+  })();
559 584
 });
560 585
 
561 586
 test(function _maybeEnd() {

Showing you all comments on commits in this comparison.

Benjamin Thomas

I'm confused, we don't like file extensions?

Felix Geisendörfer
Owner

Well, basically you cannot trust the name and extension of user uploaded files. There is a significant amount of files with misnamed extensions, especially with multi media files. Plus, certain media formats are just containers for codecs.

So the only reliable way is to yank the file through magic db (http://www.magicdb.org/) and use that.

Something went wrong with that request. Please try again.