From 2bd02420059a5293e1fccc50fd28baea52a89f15 Mon Sep 17 00:00:00 2001 From: Charlike Mike Reagent Date: Thu, 2 Apr 2020 15:26:57 +0300 Subject: [PATCH 1/3] fix: make opts.filename from #591 work with opts.keepExtensions Signed-off-by: Charlike Mike Reagent --- examples/with-koa2.js | 11 ++++++++++- src/Formidable.js | 33 ++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/examples/with-koa2.js b/examples/with-koa2.js index 1ecef737..b8cd6b62 100644 --- a/examples/with-koa2.js +++ b/examples/with-koa2.js @@ -11,7 +11,16 @@ app.on('error', (err) => { app.use(async (ctx, next) => { if (ctx.url === '/api/upload' && ctx.method.toLowerCase() === 'post') { - const form = formidable({ multiples: true }); + let i = 0; + const form = formidable({ + multiples: true, + keepExtensions: true, + // must return absolute path + filename: (part, $self) => { + i += 1; + return `${$self.uploadDir}/sasasa${i}`; + }, + }); // not very elegant, but that's for now if you don't want touse `koa-better-body` // or other middlewares. diff --git a/src/Formidable.js b/src/Formidable.js index c9a0d662..19e849a8 100644 --- a/src/Formidable.js +++ b/src/Formidable.js @@ -44,11 +44,6 @@ class IncomingForm extends EventEmitter { this.uploaddir = dir; this.uploadDir = dir; - this.options.filename = - typeof this.options.filename === 'function' - ? this.options.filename.bind(this) - : this._uploadPath.bind(this); - // initialize with null [ 'error', @@ -61,6 +56,19 @@ class IncomingForm extends EventEmitter { this[key] = null; }); + const hasRename = typeof this.options.filename === 'function'; + const rename = hasRename ? this.options.filename : this._uploadPath; + + if (this.options.keepExtensions === true && hasRename) { + this._rename = (part) => { + const resultFilepath = this.options.filename.call(this, part, this); + + return this._uploadPath(part, resultFilepath); + }; + } else { + this._rename = rename; + } + this._flushing = 0; this._fieldsSize = 0; this._fileSize = 0; @@ -290,7 +298,7 @@ class IncomingForm extends EventEmitter { this._flushing += 1; const file = new File({ - path: this.options.filename(part, this), + path: this._rename.call(this, part, this), name: part.filename, type: part.mime, hash: this.options.hash, @@ -436,14 +444,17 @@ class IncomingForm extends EventEmitter { return filename; } - _uploadPath(part) { - const name = `${this.uploadDir}${path.sep}${toHexoId()}`; + _uploadPath(part, fp) { + const name = fp || `${this.uploadDir}${path.sep}${toHexoId()}`; if (part && this.options.keepExtensions) { - let ext = path.extname(typeof part === 'string' ? part : part.filename); - ext = ext.replace(/(\.[a-z0-9]+).*/i, '$1'); + // eslint-disable-next-line no-inner-declarations + function getExt(str) { + return path.basename(str).slice(path.basename(str).indexOf('.')); + } - return `${name}${ext}`; + const filename = typeof part === 'string' ? part : part.filename; + return `${name}${getExt(filename)}`; } return name; From 0e1370fc8376b761a12b939081196c4732789c64 Mon Sep 17 00:00:00 2001 From: Charlike Mike Reagent Date: Thu, 2 Apr 2020 15:35:52 +0300 Subject: [PATCH 2/3] chore: tweaks for failing tests Signed-off-by: Charlike Mike Reagent --- src/Formidable.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Formidable.js b/src/Formidable.js index 19e849a8..5129c2f1 100644 --- a/src/Formidable.js +++ b/src/Formidable.js @@ -57,7 +57,6 @@ class IncomingForm extends EventEmitter { }); const hasRename = typeof this.options.filename === 'function'; - const rename = hasRename ? this.options.filename : this._uploadPath; if (this.options.keepExtensions === true && hasRename) { this._rename = (part) => { @@ -66,7 +65,7 @@ class IncomingForm extends EventEmitter { return this._uploadPath(part, resultFilepath); }; } else { - this._rename = rename; + this._rename = (part) => this._uploadPath(part); } this._flushing = 0; @@ -298,7 +297,7 @@ class IncomingForm extends EventEmitter { this._flushing += 1; const file = new File({ - path: this._rename.call(this, part, this), + path: this._rename(part), name: part.filename, type: part.mime, hash: this.options.hash, From 5cb4b65e5c39b5dbe04f66c53d38c1053abc4048 Mon Sep 17 00:00:00 2001 From: Charlike Mike Reagent Date: Thu, 2 Apr 2020 16:12:24 +0300 Subject: [PATCH 3/3] fix: extension problems Signed-off-by: Charlike Mike Reagent --- src/Formidable.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Formidable.js b/src/Formidable.js index 5129c2f1..5d3f7a1f 100644 --- a/src/Formidable.js +++ b/src/Formidable.js @@ -440,20 +440,29 @@ class IncomingForm extends EventEmitter { filename = filename.replace(/&#([\d]{4});/g, (_, code) => String.fromCharCode(code), ); + return filename; } + _getExtension(str) { + const basename = path.basename(str); + const firstDot = basename.indexOf('.'); + const lastDot = basename.lastIndexOf('.'); + const extname = path.extname(basename).replace(/(\.[a-z0-9]+).*/i, '$1'); + + if (firstDot === lastDot) { + return extname; + } + + return basename.slice(firstDot, lastDot) + extname; + } + _uploadPath(part, fp) { const name = fp || `${this.uploadDir}${path.sep}${toHexoId()}`; if (part && this.options.keepExtensions) { - // eslint-disable-next-line no-inner-declarations - function getExt(str) { - return path.basename(str).slice(path.basename(str).indexOf('.')); - } - const filename = typeof part === 'string' ? part : part.filename; - return `${name}${getExt(filename)}`; + return `${name}${this._getExtension(filename)}`; } return name;