blob: cd00ec833b69ae3efd0ffb3f8976316564e27ddb [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
Ed Tanous04e438c2020-10-03 08:06:26 -07002#include "http_request.hpp"
3#include "logging.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -07004#include "nlohmann/json.hpp"
5
Ed Tanousd43cd0c2020-09-30 20:46:53 -07006#include <boost/beast/http/message.hpp>
Ed Tanous7045c8d2017-04-03 10:04:37 -07007
Gunnar Mills1214b7e2020-06-04 10:11:30 -05008#include <string>
Ed Tanous7045c8d2017-04-03 10:04:37 -07009
Ed Tanous1abe55e2018-09-05 08:30:59 -070010namespace crow
11{
Ed Tanouse0d918b2018-03-27 17:41:04 -070012
Ed Tanous52cc1122020-07-18 13:51:21 -070013template <typename Adaptor, typename Handler>
Ed Tanous7045c8d2017-04-03 10:04:37 -070014class Connection;
Borawski.Lukasz9d8fd302018-01-05 14:56:09 +010015
Ed Tanous1abe55e2018-09-05 08:30:59 -070016struct Response
17{
Ed Tanous52cc1122020-07-18 13:51:21 -070018 template <typename Adaptor, typename Handler>
Ed Tanous1abe55e2018-09-05 08:30:59 -070019 friend class crow::Connection;
20 using response_type =
21 boost::beast::http::response<boost::beast::http::string_body>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070022
Ed Tanousa24526d2018-12-10 15:17:59 -080023 std::optional<response_type> stringResponse;
Ed Tanouse0d918b2018-03-27 17:41:04 -070024
Ed Tanous1abe55e2018-09-05 08:30:59 -070025 nlohmann::json jsonValue;
Ed Tanous7045c8d2017-04-03 10:04:37 -070026
Ed Tanous39e77502019-03-04 17:35:53 -080027 void addHeader(const std::string_view key, const std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070028 {
29 stringResponse->set(key, value);
Ed Tanous7045c8d2017-04-03 10:04:37 -070030 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070031
Ed Tanous39e77502019-03-04 17:35:53 -080032 void addHeader(boost::beast::http::field key, std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070033 {
34 stringResponse->set(key, value);
Ed Tanous2cd4cc12018-07-25 10:51:19 -070035 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070036
Ed Tanous1abe55e2018-09-05 08:30:59 -070037 Response() : stringResponse(response_type{})
Gunnar Mills1214b7e2020-06-04 10:11:30 -050038 {}
Ed Tanous7045c8d2017-04-03 10:04:37 -070039
Ed Tanous1abe55e2018-09-05 08:30:59 -070040 Response& operator=(const Response& r) = delete;
41
42 Response& operator=(Response&& r) noexcept
43 {
44 BMCWEB_LOG_DEBUG << "Moving response containers";
45 stringResponse = std::move(r.stringResponse);
46 r.stringResponse.emplace(response_type{});
47 jsonValue = std::move(r.jsonValue);
48 completed = r.completed;
49 return *this;
50 }
51
52 void result(boost::beast::http::status v)
53 {
54 stringResponse->result(v);
55 }
56
57 boost::beast::http::status result()
58 {
59 return stringResponse->result();
60 }
61
62 unsigned resultInt()
63 {
64 return stringResponse->result_int();
65 }
66
Ed Tanous39e77502019-03-04 17:35:53 -080067 std::string_view reason()
Ed Tanous1abe55e2018-09-05 08:30:59 -070068 {
69 return stringResponse->reason();
70 }
71
72 bool isCompleted() const noexcept
73 {
74 return completed;
75 }
76
77 std::string& body()
78 {
79 return stringResponse->body();
80 }
81
82 void keepAlive(bool k)
83 {
84 stringResponse->keep_alive(k);
85 }
86
Ed Tanousceac6f72018-12-02 11:58:47 -080087 bool keepAlive()
88 {
89 return stringResponse->keep_alive();
90 }
91
Ed Tanous1abe55e2018-09-05 08:30:59 -070092 void preparePayload()
93 {
94 stringResponse->prepare_payload();
Ed Tanous23a21a12020-07-25 04:45:05 +000095 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070096
97 void clear()
98 {
99 BMCWEB_LOG_DEBUG << this << " Clearing response containers";
100 stringResponse.emplace(response_type{});
101 jsonValue.clear();
102 completed = false;
103 }
104
Ed Tanous81ce6092020-12-17 16:54:55 +0000105 void write(std::string_view bodyPart)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700106 {
Ed Tanous81ce6092020-12-17 16:54:55 +0000107 stringResponse->body() += std::string(bodyPart);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700108 }
109
110 void end()
111 {
112 if (completed)
113 {
114 BMCWEB_LOG_ERROR << "Response was ended twice";
115 return;
116 }
117 completed = true;
118 BMCWEB_LOG_DEBUG << "calling completion handler";
119 if (completeRequestHandler)
120 {
121 BMCWEB_LOG_DEBUG << "completion handler was valid";
122 completeRequestHandler();
123 }
124 }
125
Ed Tanous81ce6092020-12-17 16:54:55 +0000126 void end(std::string_view bodyPart)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700127 {
Ed Tanous81ce6092020-12-17 16:54:55 +0000128 write(bodyPart);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700129 end();
130 }
131
132 bool isAlive()
133 {
134 return isAliveHelper && isAliveHelper();
135 }
136
137 private:
138 bool completed{};
139 std::function<void()> completeRequestHandler;
140 std::function<bool()> isAliveHelper;
141
142 // In case of a JSON object, set the Content-Type header
143 void jsonMode()
144 {
145 addHeader("Content-Type", "application/json");
146 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700147};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700148} // namespace crow