blob: 68e3f2d228eb3271c9738efa7198b4b68df74cb3 [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002#include "http_request.h"
3#include "logging.h"
4
Ed Tanous1abe55e2018-09-05 08:30:59 -07005#include "nlohmann/json.hpp"
6
7#include <boost/beast/http.hpp>
Ed Tanous7045c8d2017-04-03 10:04:37 -07008
Gunnar Mills1214b7e2020-06-04 10:11:30 -05009#include <string>
Ed Tanous7045c8d2017-04-03 10:04:37 -070010
Ed Tanous1abe55e2018-09-05 08:30:59 -070011namespace crow
12{
Ed Tanouse0d918b2018-03-27 17:41:04 -070013
Ed Tanous52cc1122020-07-18 13:51:21 -070014template <typename Adaptor, typename Handler>
Ed Tanous7045c8d2017-04-03 10:04:37 -070015class Connection;
Borawski.Lukasz9d8fd302018-01-05 14:56:09 +010016
Ed Tanous1abe55e2018-09-05 08:30:59 -070017struct Response
18{
Ed Tanous52cc1122020-07-18 13:51:21 -070019 template <typename Adaptor, typename Handler>
Ed Tanous1abe55e2018-09-05 08:30:59 -070020 friend class crow::Connection;
21 using response_type =
22 boost::beast::http::response<boost::beast::http::string_body>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070023
Ed Tanousa24526d2018-12-10 15:17:59 -080024 std::optional<response_type> stringResponse;
Ed Tanouse0d918b2018-03-27 17:41:04 -070025
Ed Tanous1abe55e2018-09-05 08:30:59 -070026 nlohmann::json jsonValue;
Ed Tanous7045c8d2017-04-03 10:04:37 -070027
Ed Tanous39e77502019-03-04 17:35:53 -080028 void addHeader(const std::string_view key, const std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070029 {
30 stringResponse->set(key, value);
Ed Tanous7045c8d2017-04-03 10:04:37 -070031 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070032
Ed Tanous39e77502019-03-04 17:35:53 -080033 void addHeader(boost::beast::http::field key, std::string_view value)
Ed Tanous1abe55e2018-09-05 08:30:59 -070034 {
35 stringResponse->set(key, value);
Ed Tanous2cd4cc12018-07-25 10:51:19 -070036 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070037
Ed Tanous1abe55e2018-09-05 08:30:59 -070038 Response() : stringResponse(response_type{})
Gunnar Mills1214b7e2020-06-04 10:11:30 -050039 {}
Ed Tanous7045c8d2017-04-03 10:04:37 -070040
Ed Tanous1abe55e2018-09-05 08:30:59 -070041 Response(Response&& r)
42 {
43 BMCWEB_LOG_DEBUG << "Moving response containers";
44 *this = std::move(r);
45 }
46
47 ~Response()
48 {
49 BMCWEB_LOG_DEBUG << this << " Destroying response";
50 }
51
52 Response& operator=(const Response& r) = delete;
53
54 Response& operator=(Response&& r) noexcept
55 {
56 BMCWEB_LOG_DEBUG << "Moving response containers";
57 stringResponse = std::move(r.stringResponse);
58 r.stringResponse.emplace(response_type{});
59 jsonValue = std::move(r.jsonValue);
60 completed = r.completed;
61 return *this;
62 }
63
64 void result(boost::beast::http::status v)
65 {
66 stringResponse->result(v);
67 }
68
69 boost::beast::http::status result()
70 {
71 return stringResponse->result();
72 }
73
74 unsigned resultInt()
75 {
76 return stringResponse->result_int();
77 }
78
Ed Tanous39e77502019-03-04 17:35:53 -080079 std::string_view reason()
Ed Tanous1abe55e2018-09-05 08:30:59 -070080 {
81 return stringResponse->reason();
82 }
83
84 bool isCompleted() const noexcept
85 {
86 return completed;
87 }
88
89 std::string& body()
90 {
91 return stringResponse->body();
92 }
93
94 void keepAlive(bool k)
95 {
96 stringResponse->keep_alive(k);
97 }
98
Ed Tanousceac6f72018-12-02 11:58:47 -080099 bool keepAlive()
100 {
101 return stringResponse->keep_alive();
102 }
103
Ed Tanous1abe55e2018-09-05 08:30:59 -0700104 void preparePayload()
105 {
106 stringResponse->prepare_payload();
Ed Tanous23a21a12020-07-25 04:45:05 +0000107 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700108
109 void clear()
110 {
111 BMCWEB_LOG_DEBUG << this << " Clearing response containers";
112 stringResponse.emplace(response_type{});
113 jsonValue.clear();
114 completed = false;
115 }
116
Ed Tanous39e77502019-03-04 17:35:53 -0800117 void write(std::string_view body_part)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700118 {
119 stringResponse->body() += std::string(body_part);
120 }
121
122 void end()
123 {
124 if (completed)
125 {
126 BMCWEB_LOG_ERROR << "Response was ended twice";
127 return;
128 }
129 completed = true;
130 BMCWEB_LOG_DEBUG << "calling completion handler";
131 if (completeRequestHandler)
132 {
133 BMCWEB_LOG_DEBUG << "completion handler was valid";
134 completeRequestHandler();
135 }
136 }
137
Ed Tanous39e77502019-03-04 17:35:53 -0800138 void end(std::string_view body_part)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700139 {
140 write(body_part);
141 end();
142 }
143
144 bool isAlive()
145 {
146 return isAliveHelper && isAliveHelper();
147 }
148
149 private:
150 bool completed{};
151 std::function<void()> completeRequestHandler;
152 std::function<bool()> isAliveHelper;
153
154 // In case of a JSON object, set the Content-Type header
155 void jsonMode()
156 {
157 addHeader("Content-Type", "application/json");
158 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700159};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700160} // namespace crow