drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.44k stars 1.1k forks source link

Unsafe Filter callbacks within lambdas #1700

Closed Mis1eader-dev closed 1 year ago

Mis1eader-dev commented 1 year ago

Describe the bug Spinning up a thread within doFilter and capturing the HttpRequestPtr parameter by value leads to a segmentation fault. This isn't the case with normal http request handlers asyncHandleHttpRequest, it works fine with them.

To Reproduce Steps to reproduce the behavior:

  1. Make two classes, one being a filter, and the other a request handler.
  2. Have a thread created within both, taking req by value.
  3. Inside the lambda print req->something.
  4. The server crashes with the filter, but it works as expected with the http request handler.

Expected behavior It should stay alive until fcb or fccb are called.

Desktop (please complete the following information):

Additional context Reason for this need is to handle IO bound synchronous calls within these threads.

Mis1eader-dev commented 1 year ago

On a clean project it worked as expected for the filter, however, in an already established project it fails the following assert:

drogon::IOThreadStorage<C>::ValueType& drogon::IOThreadStorage<C>::getThreadData() [with C = std::unordered_map<std::__cxx11::basic_string<char>, std::shared_ptr<drogon::HttpResponse> >; drogon::IOThreadStorage<C>::ValueType = std::unordered_map<std::__cxx11::basic_string<char>, std::shared_ptr<drogon::HttpResponse> >]: Assertion `idx < storage_.size()' failed.

We'll see where this goes.

Update: Apparently it doesn't crash on req accesses, it occurs on fccb()

Mis1eader-dev commented 1 year ago

Found the bug, it is caused by "locations" config entry, see the reproduceable example 29b188c @an-tao

Update: Running it in debug mode, it crashes on both a controller registered with a filter, and "locations" defined filters. It appears FilterChainCallback&& fccb is the cause, no issues if FilterCallback&& fcb is called within the thread.

Area of the crash in question is lib/inc/drogon/IOThreadStorage.h - getThreadData and lib/src/HttpAppFrameworkImpl.h - getCurrentThreadIndex