Skip to content

Commit

Permalink
Merge branch 'release/1.0.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jun 22, 2017
2 parents 1767657 + cc3211e commit 57c9b6b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,8 @@
<a name="1.0.3"></a>
## [1.0.3](https://github.com/adonisjs/adonis-middleware/compare/v1.0.2...v1.0.3) (2017-06-22)



<a name="1.0.2"></a>
## [1.0.2](https://github.com/adonisjs/adonis-middleware/compare/v1.0.1...v1.0.2) (2017-06-22)

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@adonisjs/bodyparser",
"version": "1.0.2",
"version": "1.0.3",
"description": "Body parser middleware for Adonis 4.0 and above",
"main": "index.js",
"scripts": {
Expand Down
40 changes: 36 additions & 4 deletions src/Multipart/index.js
Expand Up @@ -84,6 +84,17 @@ class Multipart {
}

this._processedStream = false

/**
* Multiparty will finish the stream when read stream
* is consumed but at times clients needs more time
* even when stream is consumed. In that case we
* should make sure all promises are resolved
* or rejected before moving forwards.
*
* @type {Object}
*/
this._pendingPromises = new Set()
}

/**
Expand Down Expand Up @@ -124,7 +135,19 @@ class Multipart {
this.jar.track(fileInstance)
}

return Promise.resolve(handler.callback(fileInstance))
return new Promise((resolve, reject) => {
const filePromise = Promise.resolve(handler.callback(fileInstance))
this._pendingPromises.add(filePromise)

filePromise
.then(() => {
this._pendingPromises.delete(filePromise)
resolve()
}).catch((error) => {
this._pendingPromises.delete(filePromise)
reject(error)
})
})
}

/**
Expand All @@ -146,8 +169,13 @@ class Multipart {
form.on('error', reject)
form.on('part', (part) => {
this.onPart(part)
.then(() => part.resume())
.catch((error) => form.emit('error', error))
.then(() => {
part.resume()
if (form.flushing <= 0 && this._pendingPromises.size === 0) {
resolve()
}
})
.catch((error) => form.emit('error', error))
})

form.on('field', (name, value) => {
Expand All @@ -156,7 +184,11 @@ class Multipart {
}
})

form.on('close', resolve)
form.on('close', () => {
if (this._pendingPromises.size === 0) {
resolve()
}
})
form.parse(this.req)
})
}
Expand Down
36 changes: 36 additions & 0 deletions test/unit/multipart.spec.js
Expand Up @@ -15,6 +15,11 @@ const http = require('http')
const supertest = require('supertest')
const Multipart = require('../../src/Multipart')
const fs = require('fs-extra')
const sleep = function (time) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}

const exists = async function (location) {
const fileExists = await fs.exists(location)
Expand Down Expand Up @@ -921,4 +926,35 @@ test.group('Multipart', () => {

assert.equal(text, 'true')
})

test('wait for file handler to finish before ending the request', async (assert) => {
const server = http.createServer((req, res) => {
const multipart = new Multipart({ request: req })
let ended = false
multipart.file('*', {}, async (file) => {
await file.read()
await sleep(10)
ended = true
})

multipart
.process()
.then(() => {
res.writeHead(200)
res.write(String(ended))
res.end()
}).catch((error) => {
res.writeHead(500)
res.write(error.message)
res.end()
})
})

const { text } = await supertest(server)
.get('/')
.attach('package', path.join(__dirname, '../../package.json'))
.expect(200)

assert.equal(text, 'true')
})
})

0 comments on commit 57c9b6b

Please sign in to comment.