alexa-js / alexa-verifier-middleware

An express middleware that verifies HTTP requests sent to an Alexa skill are sent from Amazon.
MIT License
31 stars 6 forks source link

req.on('end', function() {}) never fires, middleware hangs #14

Closed dblock closed 7 years ago

dblock commented 7 years ago

With another body-parser above it (see https://github.com/alexa-js/alexa-app/issues/152) the middleware hangs. The middleware needs to read and process the entire request body in order for the validation to work, and express doesn't expose that on the request object directly. So it accumulates the whole data of the request before any processing happens. That doesn't explain why the request would hang.

tejashah88 commented 7 years ago

Is this bug solved yet, or is there still a problem?

dblock commented 7 years ago

I believe it's not solved. The middleware part was addressed, ie. the way alexa-app uses alexa-verifier-middleware doesn't exhibit this behavior unless the user throws a bodyparser above it. When the user does, the middleware hangs.

tejashah88 commented 7 years ago

I did some more testing and apparently, the body-parser seems to swallow up the entire request. This is because the req.on('data', function() {}) is never fired in the first place.

I dug through the body-parser source code, specifically json.js, and I found that there are some debug statements that can be printed when you set the environment variable of DEBUG. I did that and this is the relevant output that I got:

image

If you look at the middle, there is a debug line of interest: "read body". I traced it to read.js and here's some interesting results:

image

According to the few comments that I found, the body-parser seems to be reading the entire request body and then processing it.

dblock commented 7 years ago

Makes sense, this confirms the bug. There needs to be some code in the middleware that skips it when there's not going to be any data.

tejashah88 commented 7 years ago

I disagree, as the purpose of this module would be defeated. If someone used a similar practice to test_alexa_verifier_middleware_hangs.js, he/she wouldn't really know why the verification fails until we told him/her.

I'd say that the module should throw an error if the body is already processed and tell the user to change the code as necessary. An example would be:

if (req._body) {
  return res.status(401).json({ status: 'failure', reason: 'The incoming body was already parsed! Are you sure that this module is loaded before any body-parser modules?' })
}
dblock commented 7 years ago

Yes you're right.