104e438cbSEd Tanous #pragma once 204e438cbSEd Tanous #include "http_request.hpp" 304e438cbSEd Tanous #include "logging.hpp" 404e438cbSEd Tanous #include "nlohmann/json.hpp" 504e438cbSEd Tanous 604e438cbSEd Tanous #include <boost/beast/http/message.hpp> 704e438cbSEd Tanous 804e438cbSEd Tanous #include <string> 904e438cbSEd Tanous 1004e438cbSEd Tanous namespace crow 1104e438cbSEd Tanous { 1204e438cbSEd Tanous 1304e438cbSEd Tanous template <typename Adaptor, typename Handler> 1404e438cbSEd Tanous class Connection; 1504e438cbSEd Tanous 1604e438cbSEd Tanous struct Response 1704e438cbSEd Tanous { 1804e438cbSEd Tanous template <typename Adaptor, typename Handler> 1904e438cbSEd Tanous friend class crow::Connection; 2004e438cbSEd Tanous using response_type = 2104e438cbSEd Tanous boost::beast::http::response<boost::beast::http::string_body>; 2204e438cbSEd Tanous 2304e438cbSEd Tanous std::optional<response_type> stringResponse; 2404e438cbSEd Tanous 2504e438cbSEd Tanous nlohmann::json jsonValue; 2604e438cbSEd Tanous 2704e438cbSEd Tanous void addHeader(const std::string_view key, const std::string_view value) 2804e438cbSEd Tanous { 2904e438cbSEd Tanous stringResponse->set(key, value); 3004e438cbSEd Tanous } 3104e438cbSEd Tanous 3204e438cbSEd Tanous void addHeader(boost::beast::http::field key, std::string_view value) 3304e438cbSEd Tanous { 3404e438cbSEd Tanous stringResponse->set(key, value); 3504e438cbSEd Tanous } 3604e438cbSEd Tanous 3704e438cbSEd Tanous Response() : stringResponse(response_type{}) 3804e438cbSEd Tanous {} 3904e438cbSEd Tanous 4004e438cbSEd Tanous Response& operator=(const Response& r) = delete; 4104e438cbSEd Tanous 4204e438cbSEd Tanous Response& operator=(Response&& r) noexcept 4304e438cbSEd Tanous { 4404e438cbSEd Tanous BMCWEB_LOG_DEBUG << "Moving response containers"; 4504e438cbSEd Tanous stringResponse = std::move(r.stringResponse); 4604e438cbSEd Tanous r.stringResponse.emplace(response_type{}); 4704e438cbSEd Tanous jsonValue = std::move(r.jsonValue); 4804e438cbSEd Tanous completed = r.completed; 4904e438cbSEd Tanous return *this; 5004e438cbSEd Tanous } 5104e438cbSEd Tanous 5204e438cbSEd Tanous void result(boost::beast::http::status v) 5304e438cbSEd Tanous { 5404e438cbSEd Tanous stringResponse->result(v); 5504e438cbSEd Tanous } 5604e438cbSEd Tanous 5704e438cbSEd Tanous boost::beast::http::status result() 5804e438cbSEd Tanous { 5904e438cbSEd Tanous return stringResponse->result(); 6004e438cbSEd Tanous } 6104e438cbSEd Tanous 6204e438cbSEd Tanous unsigned resultInt() 6304e438cbSEd Tanous { 6404e438cbSEd Tanous return stringResponse->result_int(); 6504e438cbSEd Tanous } 6604e438cbSEd Tanous 6704e438cbSEd Tanous std::string_view reason() 6804e438cbSEd Tanous { 6904e438cbSEd Tanous return stringResponse->reason(); 7004e438cbSEd Tanous } 7104e438cbSEd Tanous 7204e438cbSEd Tanous bool isCompleted() const noexcept 7304e438cbSEd Tanous { 7404e438cbSEd Tanous return completed; 7504e438cbSEd Tanous } 7604e438cbSEd Tanous 7704e438cbSEd Tanous std::string& body() 7804e438cbSEd Tanous { 7904e438cbSEd Tanous return stringResponse->body(); 8004e438cbSEd Tanous } 8104e438cbSEd Tanous 8204e438cbSEd Tanous void keepAlive(bool k) 8304e438cbSEd Tanous { 8404e438cbSEd Tanous stringResponse->keep_alive(k); 8504e438cbSEd Tanous } 8604e438cbSEd Tanous 8704e438cbSEd Tanous bool keepAlive() 8804e438cbSEd Tanous { 8904e438cbSEd Tanous return stringResponse->keep_alive(); 9004e438cbSEd Tanous } 9104e438cbSEd Tanous 9204e438cbSEd Tanous void preparePayload() 9304e438cbSEd Tanous { 9404e438cbSEd Tanous stringResponse->prepare_payload(); 9504e438cbSEd Tanous } 9604e438cbSEd Tanous 9704e438cbSEd Tanous void clear() 9804e438cbSEd Tanous { 9904e438cbSEd Tanous BMCWEB_LOG_DEBUG << this << " Clearing response containers"; 10004e438cbSEd Tanous stringResponse.emplace(response_type{}); 10104e438cbSEd Tanous jsonValue.clear(); 10204e438cbSEd Tanous completed = false; 10304e438cbSEd Tanous } 10404e438cbSEd Tanous 105*81ce609eSEd Tanous void write(std::string_view bodyPart) 10604e438cbSEd Tanous { 107*81ce609eSEd Tanous stringResponse->body() += std::string(bodyPart); 10804e438cbSEd Tanous } 10904e438cbSEd Tanous 11004e438cbSEd Tanous void end() 11104e438cbSEd Tanous { 11204e438cbSEd Tanous if (completed) 11304e438cbSEd Tanous { 11404e438cbSEd Tanous BMCWEB_LOG_ERROR << "Response was ended twice"; 11504e438cbSEd Tanous return; 11604e438cbSEd Tanous } 11704e438cbSEd Tanous completed = true; 11804e438cbSEd Tanous BMCWEB_LOG_DEBUG << "calling completion handler"; 11904e438cbSEd Tanous if (completeRequestHandler) 12004e438cbSEd Tanous { 12104e438cbSEd Tanous BMCWEB_LOG_DEBUG << "completion handler was valid"; 12204e438cbSEd Tanous completeRequestHandler(); 12304e438cbSEd Tanous } 12404e438cbSEd Tanous } 12504e438cbSEd Tanous 126*81ce609eSEd Tanous void end(std::string_view bodyPart) 12704e438cbSEd Tanous { 128*81ce609eSEd Tanous write(bodyPart); 12904e438cbSEd Tanous end(); 13004e438cbSEd Tanous } 13104e438cbSEd Tanous 13204e438cbSEd Tanous bool isAlive() 13304e438cbSEd Tanous { 13404e438cbSEd Tanous return isAliveHelper && isAliveHelper(); 13504e438cbSEd Tanous } 13604e438cbSEd Tanous 13704e438cbSEd Tanous private: 13804e438cbSEd Tanous bool completed{}; 13904e438cbSEd Tanous std::function<void()> completeRequestHandler; 14004e438cbSEd Tanous std::function<bool()> isAliveHelper; 14104e438cbSEd Tanous 14204e438cbSEd Tanous // In case of a JSON object, set the Content-Type header 14304e438cbSEd Tanous void jsonMode() 14404e438cbSEd Tanous { 14504e438cbSEd Tanous addHeader("Content-Type", "application/json"); 14604e438cbSEd Tanous } 14704e438cbSEd Tanous }; 14804e438cbSEd Tanous } // namespace crow 149