index.js
function multipart (handler, done, opts) {
    if (typeof handler !== 'function') {
      throw new Error('handler must be a function')
    }

    if (typeof done !== 'function') {
      throw new Error('the callback must be a function')
    }

    if (!this.isMultipart()) {
      done(new Error('the request is not multipart'))
      return
    }

    const log = this.log

    log.debug('starting multipart parsing')

    const req = this.req

    const busboyOptions = deepmerge.all([{ headers: req.headers }, options || {}, opts || {}])
    const stream = new Busboy(busboyOptions)
    var completed = false
    var files = 0
    var count = 0
    var callDoneOnNextEos = false

    req.on('error', function (err) {
      stream.destroy()
      if (!completed) {
        completed = true
        done(err)
      }
    })

    stream.on('finish', function () {
      log.debug('finished multipart parsing')
      if (!completed && count === files) {
        completed = true
        setImmediate(done)
      } else {
        callDoneOnNextEos = true
      }
    })

    stream.on('file', wrap)

    req.pipe(stream)

    function wrap (field, file, filename, encoding, mimetype) {
      log.debug({ field, filename, encoding, mimetype }, 'parsing part')
      files++
      eos(file, waitForFiles)
      handler(field, file, filename, encoding, mimetype)
    }

    function waitForFiles (err) {
      if (err) {
        completed = true
        done(err)
        return
      }

      if (completed) {
        return
      }

      ++count
      if (callDoneOnNextEos && count === files) {
        completed = true
        done()
      }
    }

    return stream
  }
function multipart (handler, done, opts) {
    if (typeof handler !== 'function') {
      throw new Error('handler must be a function')
    }

    if (typeof done !== 'function') {
      throw new Error('the callback must be a function')
    }

    if (!this.isMultipart()) {
      done(new Error('the request is not multipart'))
      return
    }

    const log = this.log

    log.debug('starting multipart parsing')

    const req = this.req

    const busboyOptions = deepmerge.all([{ headers: req.headers }, options || {}, opts || {}])
    const stream = new Busboy(busboyOptions)
    var completed = false
    var files = 0
    var count = 0
    var callDoneOnNextEos = false

    req.on('error', function (err) {
      stream.destroy()
      if (!completed) {
        completed = true
        done(err)
      }
    })

    stream.on('finish', function () {
      log.debug('finished multipart parsing')
      if (!completed && count === files) {
        completed = true
        setImmediate(done)
      } else {
        callDoneOnNextEos = true
      }
    })

    stream.on('file', wrap)

    req.pipe(stream)

    function wrap (field, file, filename, encoding, mimetype) {
      log.debug({ field, filename, encoding, mimetype }, 'parsing part')
      files++
      eos(file, waitForFiles)
      handler(field, file, filename, encoding, mimetype)
    }

    function waitForFiles (err) {
      if (err) {
        completed = true
        done(err)
        return
      }

      if (completed) {
        return
      }

      ++count
      if (callDoneOnNextEos && count === files) {
        completed = true
        done()
      }
    }

    return stream
  }
function multipart ( handler , done , opts ) { if ( typeof handler !== 'function' ) { throw new Error ( 'handler must be a function' ) } if ( typeof done !== 'function' ) { throw new Error ( 'the callback must be a function' ) } if ( ! this . isMultipart ( ) ) { done ( new Error ( 'the request is not multipart' ) ) return } const log = this . log log . debug ( 'starting multipart parsing' ) const req = this . req const busboyOptions = deepmerge . all ( [ { headers : req . headers } , options || { } , opts || { } ] ) const stream = new Busboy ( busboyOptions ) var completed = false var files = 0 var count = 0 var callDoneOnNextEos = false req . on ( 'error' , function ( err ) { stream . destroy ( ) if ( ! completed ) { completed = true done ( err ) } } ) stream . on ( 'finish' , function ( ) { log . debug ( 'finished multipart parsing' ) if ( ! completed && count === files ) { completed = true setImmediate ( done ) } else { callDoneOnNextEos = true } } ) stream . on ( 'file' , wrap ) req . pipe ( stream ) function wrap ( field , file , filename , encoding , mimetype ) { log . debug ( { field , filename , encoding , mimetype } , 'parsing part' ) files ++ eos ( file , waitForFiles ) handler ( field , file , filename , encoding , mimetype ) } function waitForFiles ( err ) { if ( err ) { completed = true done ( err ) return } if ( completed ) { return } ++ count if ( callDoneOnNextEos && count === files ) { completed = true done ( ) } } return stream }
handler definition is in multipart-readstream handler(field, file, filename, encoding, mimetype) opts is a per-request override for the options object
handler definition is in multipart - readstream handler ( field file filename encoding mimetype ) opts is a per - request override for the options object