#pragma once #include #include #include "crow/json.h" #include "crow/http_request.h" #include "crow/ci_map.h" namespace crow { template class Connection; struct response { template friend class crow::Connection; int code{200}; std::string body; json::wvalue json_value; // `headers' stores HTTP headers. ci_map headers; void set_header(std::string key, std::string value) { headers.erase(key); headers.emplace(std::move(key), std::move(value)); } void add_header(std::string key, std::string value) { headers.emplace(std::move(key), std::move(value)); } const std::string& get_header_value(const std::string& key) { return crow::get_header_value(headers, key); } response() {} explicit response(int code) : code(code) {} response(std::string body) : body(std::move(body)) {} response(json::wvalue&& json_value) : json_value(std::move(json_value)) { json_mode(); } response(int code, std::string body) : code(code), body(std::move(body)) {} response(const json::wvalue& json_value) : body(json::dump(json_value)) { json_mode(); } response(int code, const json::wvalue& json_value) : code(code), body(json::dump(json_value)) { json_mode(); } response(response&& r) { *this = std::move(r); } response& operator = (const response& r) = delete; response& operator = (response&& r) noexcept { body = std::move(r.body); json_value = std::move(r.json_value); code = r.code; headers = std::move(r.headers); completed_ = r.completed_; return *this; } bool is_completed() const noexcept { return completed_; } void clear() { body.clear(); json_value.clear(); code = 200; headers.clear(); completed_ = false; } void redirect(const std::string& location) { code = 301; set_header("Location", location); } void write(const std::string& body_part) { body += body_part; } void end() { if (!completed_) { completed_ = true; if (complete_request_handler_) { complete_request_handler_(); } } } void end(const std::string& body_part) { body += body_part; end(); } bool is_alive() { return is_alive_helper_ && is_alive_helper_(); } private: bool completed_{}; std::function complete_request_handler_; std::function is_alive_helper_; //In case of a JSON object, set the Content-Type header void json_mode() { set_header("Content-Type", "application/json"); } }; }