Koa middleware breaks execution flow, returns BadRequest Error [ERRCONNABORTED]

601 Views Asked by At

I have defined my custom middleware as below. It basically fetches urlencoded form params and sets the urlencoded string into the headers for later use. I had to go down this route because for requests of type application/x-www-form-urlencoded, only koa-bodyparser supports getting the raw urlencoded string with the form parameters. I'm however unable to use it due to the fact that it does not support files. My middleware is defined as below:

const rawBody = require('raw-body')
const contentType = require('content-type')

function rawUrlEncodedFormData() {
  return async function setUrlEncodedHeader(ctx, next) {
    if (ctx.path === '/v1/urlencoded') {
      const rawRequestBody = await rawBody(ctx.req, {
        length: ctx.get('content-length'),
        encoding: contentType.parse(ctx.req).parameters.charset,
      })
      const urlEncodedString = rawRequestBody.toString('utf-8')
      console.log('form urlencoded params:', urlEncodedString)
      ctx.set('urlencoded-form-string', urlEncodedString)
      await next()
    }
    await next()
  }
}

module.exports = rawUrlEncodedFormData

I then use it alongside other middlewares like:

const middlewares = () =>
  koaCompose([
    Cors(),
    requestId(),
    logger(log),
    responseTime({
      logger: log,
    }),
    rawUrlEncodedFormData(),
    koaBody({
      multipart: true,
    }),
    redis({
      redisURL: config.redis.url,
    }),
    authorize(),
  ])

module.exports = middlewares

However, when I issue a call to that endpoint: 1. The urlencoded form parameters string is fetched correctly. 2. The request (and the application) just hangs after

Is there something i'm missing? The controller function registered to this route is not called at all. I get the following error instead

"request aborted","name":"BadRequestError","stack":"BadRequestError: request aborted\n at IncomingMessage.onAborted

1

There are 1 best solutions below

0
vsenko On

There is a path in your code that executes await next() two times. Consider refactoring it this way:

const rawBody = require('raw-body')
const contentType = require('content-type')

function rawUrlEncodedFormData() {
  return async function setUrlEncodedHeader(ctx, next) {
    if (ctx.path === '/v1/urlencoded') {
      const rawRequestBody = await rawBody(ctx.req, {
        length: ctx.get('content-length'),
        encoding: contentType.parse(ctx.req).parameters.charset,
      })
      const urlEncodedString = rawRequestBody.toString('utf-8')
      console.log('form urlencoded params:', urlEncodedString)
      ctx.set('urlencoded-form-string', urlEncodedString)
    }
    await next()
  }
}

module.exports = rawUrlEncodedFormData