ellzey/libevhtp — pull request #34 by janoberst (2012-01-27 14:51:23+00:00)
Title: evhtp_request_pause has no effect if an error occurs after the callback

Upon receiving a callback that has been set with evhtp_set_cb, my code pauses the request with evhtp_request_pause and passes the evhtp_request_t struct on to an async Redis callback. Once the database gets its result, the req struct is passed back into another callback in my code where I use evhtp_request_resume to resume the request and eventually call evhtp_send_reply.

Somehow ApacheBench creates broken requests on my Mac OS system that result in an error by evhtp's http parser after the callback has already occured.

The parser reacts to that by closing the connection and free()s both the connection and the request struct. At that point I have already passed on the request to Redis and won't notice that the parser has already free'd and closed the connection. Once my Redis callback is executed, the request is no longer valid and results in a segfault.

Unfortunately there is no way for me to figure out if a request is still active or not, so the only way I see to fix this is to make the parser respect a PAUSEd request. I'm not familiar enough with libevhtp to really figure out if I have to do some more work on this. For now this (ugly hack) seems to resolve my issue:

* prohibits the request parser to free() a connection & request upon getting an error after a callback has occured that uses request_pause
* has essentially the same effect as returning PAUSE in one of the parser-related on_ callbacks
* if a request calls request_pause, the request struct won't be freed before the request gets resumed

I am not sure if the parser runs its cleanup code for paused requests eventually. If not, that could be deferred until the request is resumed...