#include #include #include #include #include using std::cout; using std::endl; #define nullptr NULL static volatile bool run_loop = true; static MHD_Daemon *ctx = nullptr; static MHD_Response *response = nullptr; static std::vector susspended; void sighandler(int) { run_loop = false; } int handle_access(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { static int second_call_marker; static int third_call_marker; if (*con_cls == nullptr) { cout << "New connection" << endl; *con_cls = &second_call_marker; return MHD_YES; } else if (*con_cls == &second_call_marker) { cout << "Suspending connection" << endl; MHD_suspend_connection(connection); susspended.push_back(connection); *con_cls = &third_call_marker; return MHD_YES; } else { cout << "Send response" << endl; return MHD_queue_response(connection, 200, response); } } int main(int argc, char *argv[]) { std::signal(SIGINT, &sighandler); std::signal(SIGINT, &sighandler); ctx = MHD_start_daemon(MHD_USE_DUAL_STACK //| MHD_USE_EPOLL | MHD_USE_SUSPEND_RESUME | MHD_USE_DEBUG, 8080, nullptr, nullptr, &handle_access, nullptr, MHD_OPTION_END); response = MHD_create_response_from_buffer(4, const_cast("TEST"), MHD_RESPMEM_PERSISTENT); while (run_loop) { int max; fd_set rs, ws, es; struct timeval tv; struct timeval *tvp; FD_ZERO (&rs); FD_ZERO (&ws); FD_ZERO (&es); cout << "Wait for IO activity" << endl; MHD_UNSIGNED_LONG_LONG mhd_timeout = -1LL; MHD_get_fdset(ctx, &rs, &ws, &es, &max); if (MHD_get_timeout(ctx, &mhd_timeout) == MHD_YES) { tv.tv_sec = mhd_timeout / 1000; tv.tv_usec = (mhd_timeout % 1000) * 1000; tvp = &tv; } else { tvp = nullptr; } select(max + 1, &rs, &ws, &es, tvp); MHD_run_from_select(ctx, &rs, &ws, &es); for (MHD_Connection *connection : susspended) { cout << "Resume connection" << endl; MHD_resume_connection(connection); MHD_run (ctx); } susspended.clear(); } cout << "Stop server" << endl; MHD_stop_daemon(ctx); }