blob: a983d4ae519042defd63ee09a31200a06b2325ae [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
Ed Tanous04e438c2020-10-03 08:06:26 -07002#include "logging.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -07003#include "nlohmann/json.hpp"
4
Ed Tanousd43cd0c2020-09-30 20:46:53 -07005#include <boost/beast/http/message.hpp>
Ed Tanousd4b6c662021-03-10 13:29:30 -08006#include <boost/beast/http/string_body.hpp>
Ed Tanous7045c8d2017-04-03 10:04:37 -07007
Ed Tanous8a9a25c2021-05-11 14:50:58 -07008#include <optional>
Gunnar Mills1214b7e2020-06-04 10:11:30 -05009#include <string>
Ed Tanous8a9a25c2021-05-11 14:50:58 -070010#include <string_view>
Ed Tanous7045c8d2017-04-03 10:04:37 -070011
Ed Tanous1abe55e2018-09-05 08:30:59 -070012namespace crow
13{
Ed Tanouse0d918b2018-03-27 17:41:04 -070014
Ed Tanous52cc1122020-07-18 13:51:21 -070015template <typename Adaptor, typename Handler>
Ed Tanous7045c8d2017-04-03 10:04:37 -070016class Connection;
Borawski.Lukasz9d8fd302018-01-05 14:56:09 +010017
Ed Tanous1abe55e2018-09-05 08:30:59 -070018struct Response
19{
Ed Tanous52cc1122020-07-18 13:51:21 -070020 template <typename Adaptor, typename Handler>
Ed Tanous1abe55e2018-09-05 08:30:59 -070021 friend class crow::Connection;
22 using response_type =
23 boost::beast::http::response<boost::beast::http::string_body>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070024
Ed Tanousa24526d2018-12-10 15:17:59 -080025 std::optional<response_type> stringResponse;
Ed Tanouse0d918b2018-03-27 17:41:04 -070026
Ed Tanous1abe55e2018-09-05 08:30:59 -070027 nlohmann::json jsonValue;
Ed Tanous7045c8d2017-04-03 10:04:37 -070028
Ed Tanous39e77502019-03-04 17:35:53 -080029 void addHeader(const std::string_view key, const std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070030 {
31 stringResponse->set(key, value);
Ed Tanous7045c8d2017-04-03 10:04:37 -070032 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070033
Ed Tanous39e77502019-03-04 17:35:53 -080034 void addHeader(boost::beast::http::field key, std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070035 {
36 stringResponse->set(key, value);
Ed Tanous2cd4cc12018-07-25 10:51:19 -070037 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070038
Ed Tanous1abe55e2018-09-05 08:30:59 -070039 Response() : stringResponse(response_type{})
Gunnar Mills1214b7e2020-06-04 10:11:30 -050040 {}
Ed Tanous7045c8d2017-04-03 10:04:37 -070041
Ed Tanous1abe55e2018-09-05 08:30:59 -070042 Response& operator=(const Response& r) = delete;
43
44 Response& operator=(Response&& r) noexcept
45 {
46 BMCWEB_LOG_DEBUG << "Moving response containers";
47 stringResponse = std::move(r.stringResponse);
48 r.stringResponse.emplace(response_type{});
49 jsonValue = std::move(r.jsonValue);
50 completed = r.completed;
51 return *this;
52 }
53
54 void result(boost::beast::http::status v)
55 {
56 stringResponse->result(v);
57 }
58
59 boost::beast::http::status result()
60 {
61 return stringResponse->result();
62 }
63
64 unsigned resultInt()
65 {
66 return stringResponse->result_int();
67 }
68
Ed Tanous39e77502019-03-04 17:35:53 -080069 std::string_view reason()
Ed Tanous1abe55e2018-09-05 08:30:59 -070070 {
71 return stringResponse->reason();
72 }
73
74 bool isCompleted() const noexcept
75 {
76 return completed;
77 }
78
79 std::string& body()
80 {
81 return stringResponse->body();
82 }
83
84 void keepAlive(bool k)
85 {
86 stringResponse->keep_alive(k);
87 }
88
Ed Tanousceac6f72018-12-02 11:58:47 -080089 bool keepAlive()
90 {
91 return stringResponse->keep_alive();
92 }
93
Ed Tanous1abe55e2018-09-05 08:30:59 -070094 void preparePayload()
95 {
96 stringResponse->prepare_payload();
Ed Tanous23a21a12020-07-25 04:45:05 +000097 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070098
99 void clear()
100 {
101 BMCWEB_LOG_DEBUG << this << " Clearing response containers";
102 stringResponse.emplace(response_type{});
103 jsonValue.clear();
104 completed = false;
105 }
106
Ed Tanous81ce6092020-12-17 16:54:55 +0000107 void write(std::string_view bodyPart)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700108 {
Ed Tanous81ce6092020-12-17 16:54:55 +0000109 stringResponse->body() += std::string(bodyPart);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700110 }
111
112 void end()
113 {
114 if (completed)
115 {
116 BMCWEB_LOG_ERROR << "Response was ended twice";
117 return;
118 }
119 completed = true;
120 BMCWEB_LOG_DEBUG << "calling completion handler";
121 if (completeRequestHandler)
122 {
123 BMCWEB_LOG_DEBUG << "completion handler was valid";
124 completeRequestHandler();
125 }
126 }
127
Ed Tanous81ce6092020-12-17 16:54:55 +0000128 void end(std::string_view bodyPart)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700129 {
Ed Tanous81ce6092020-12-17 16:54:55 +0000130 write(bodyPart);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700131 end();
132 }
133
134 bool isAlive()
135 {
136 return isAliveHelper && isAliveHelper();
137 }
138
John Edward Broadbent4147b8a2021-07-19 16:52:24 -0700139 void setCompleteRequestHandler(std::function<void()> newHandler)
140 {
141 completeRequestHandler = std::move(newHandler);
142 }
143
Ed Tanous1abe55e2018-09-05 08:30:59 -0700144 private:
145 bool completed{};
146 std::function<void()> completeRequestHandler;
147 std::function<bool()> isAliveHelper;
148
149 // In case of a JSON object, set the Content-Type header
150 void jsonMode()
151 {
152 addHeader("Content-Type", "application/json");
153 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700154};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700155} // namespace crow