#pragma once #include #include #include #include #include struct common_params; // generator-like API for HTTP response generation // this object response with one of the 2 modes: // 1) normal response: `data` contains the full response body // 2) streaming response: each call to next(output) generates the next chunk // when next(output) returns false, no more data after the current chunk // note: some chunks can be empty, in which case no data is sent for that chunk struct server_http_res { std::string content_type = "application/json; charset=utf-8"; int status = 200; std::string data; std::map headers; // TODO: move this to a virtual function once we have proper polymorphism support std::function next = nullptr; bool is_stream() const { return next != nullptr; } virtual ~server_http_res() = default; }; // unique pointer, used by set_chunked_content_provider // httplib requires the stream provider to be stored in heap using server_http_res_ptr = std::unique_ptr; struct server_http_req { std::map params; // path_params + query_params std::map headers; // reserved for future use std::string path; // reserved for future use std::string body; const std::function & should_stop; std::string get_param(const std::string & key, const std::string & def = "") const { auto it = params.find(key); if (it != params.end()) { return it->second; } return def; } }; struct server_http_context { class Impl; std::unique_ptr pimpl; std::thread thread; // server thread std::atomic is_ready = false; std::string path_prefix; std::string hostname; int port; server_http_context(); ~server_http_context(); bool init(const common_params & params); bool start(); void stop() const; // note: the handler should never throw exceptions using handler_t = std::function; void get(const std::string & path, const handler_t & handler) const; void post(const std::string & path, const handler_t & handler) const; // for debugging std::string listening_address; };