diff --git a/README.md b/README.md index 52fc731d..69bc1797 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ Key | Description `fileFilter` | Function to control which files are accepted `limits` | Limits of the uploaded data `preservePath` | Keep the full path of files instead of just the base name +`charset` | For multipart forms, the default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). **Default**: `'latin1'`. In an average web app, only `dest` might be required, and configured as shown in the following example. diff --git a/index.js b/index.js index d5b67eba..7d2b580a 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,8 @@ function Multer (options) { this.limits = options.limits this.preservePath = options.preservePath + // TODO: next major version change default to utf-8 + this.charset = options.charset || 'latin1' this.fileFilter = options.fileFilter || allowAll } @@ -47,6 +49,7 @@ Multer.prototype._makeMiddleware = function (fields, fileStrategy) { return { limits: this.limits, preservePath: this.preservePath, + charset: this.charset, storage: this.storage, fileFilter: wrappedFileFilter, fileStrategy: fileStrategy @@ -77,6 +80,7 @@ Multer.prototype.any = function () { return { limits: this.limits, preservePath: this.preservePath, + charset: this.charset, storage: this.storage, fileFilter: this.fileFilter, fileStrategy: 'ARRAY' diff --git a/lib/make-middleware.js b/lib/make-middleware.js index 81a90cf6..09b55a00 100644 --- a/lib/make-middleware.js +++ b/lib/make-middleware.js @@ -25,6 +25,7 @@ function makeMiddleware (setup) { var fileFilter = options.fileFilter var fileStrategy = options.fileStrategy var preservePath = options.preservePath + var defParamCharset = options.charset req.body = Object.create(null) @@ -35,7 +36,12 @@ function makeMiddleware (setup) { var busboy try { - busboy = Busboy({ headers: req.headers, limits: limits, preservePath: preservePath }) + busboy = Busboy({ + headers: req.headers, + limits, + preservePath, + defParamCharset + }) } catch (err) { return next(err) } diff --git a/test/unicode.js b/test/unicode.js index 851b0ebc..1c1bd78c 100644 --- a/test/unicode.js +++ b/test/unicode.js @@ -60,3 +60,58 @@ describe('Unicode', function () { }) }) }) + +describe('UTF-8 filenames', function () { + var uploadDir, upload + + beforeEach(function (done) { + temp.mkdir(function (err, path) { + if (err) return done(err) + + var storage = multer.diskStorage({ + destination: path, + filename: function (req, file, cb) { + cb(null, file.originalname) + } + }) + + uploadDir = path + upload = multer({ storage: storage, charset: 'utf-8' }) + + done() + }) + }) + + afterEach(function (done) { + rimraf(uploadDir, done) + }) + + it('should handle UTF-8 filenames', function (done) { + var req = new stream.PassThrough() + var boundary = 'AaB03x' + var body = [ + '--' + boundary, + 'Content-Disposition: form-data; name="small0"; filename="ÖoϪ.dat"', + 'Content-Type: text/plain', + '', + 'test with UTF-8 filename', + '--' + boundary + '--' + ].join('\r\n') + + req.headers = { + 'content-type': 'multipart/form-data; boundary=' + boundary, + 'content-length': body.length + } + + req.end(body) + + upload.single('small0')(req, null, function (err) { + assert.ifError(err) + + assert.strictEqual(req.file.originalname, 'ÖoϪ.dat') + assert.strictEqual(req.file.fieldname, 'small0') + + done() + }) + }) +})