forked from expresscpp/expresscpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathresponse.cpp
More file actions
87 lines (69 loc) · 2.51 KB
/
response.cpp
File metadata and controls
87 lines (69 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "expresscpp/response.hpp"
#include "boost/uuid/uuid_generators.hpp"
#include "boost/uuid/uuid_io.hpp"
#include "expresscpp/console.hpp"
#include "expresscpp/impl/session.hpp"
namespace expresscpp {
Response::Response(Session* session) : session_(session) {
// not asserting here as we want to pass nullptr to be able to use the response without beast for testing
// assert(session_ != nullptr);
uuid_ = boost::uuids::random_generator()();
Console::Debug(fmt::format("Response created \"{}\"", boostUUIDToString(uuid_)));
}
void Response::SetStatus(const uint16_t status) {
costum_status_code_ = true;
status_ = status;
res.result(status);
}
void Response::KeepAlive(bool alive) {
res.keep_alive(alive);
}
void Response::Send() {
res.prepare_payload();
SendInternal();
}
void Response::Send(std::string message) {
// res.set(boost::beast::http::field::server, BOOST_BEAST_VERSION_STRING);
if (!costum_status_code_) res.result(boost::beast::http::status::ok);
if (res["Content-Type"].empty()) {
res.set(boost::beast::http::field::content_type, "text/html");
}
res.body() = std::string(message);
res.prepare_payload();
SendInternal();
}
void Response::Json(std::string_view json_string) {
if (!costum_status_code_) res.result(boost::beast::http::status::ok);
res.set(boost::beast::http::field::server, BOOST_BEAST_VERSION_STRING);
res.set(boost::beast::http::field::content_type, "application/json");
res.body() = std::string(json_string);
res.prepare_payload();
SendInternal();
}
bool Response::ResponseSent() const {
return response_sent_;
}
void Response::SendInternal() {
if (response_sent_) {
Console::Error("ERROR: response already sent");
return;
}
response_sent_ = true;
// The lifetime of the message has to extend
// for the duration of the async operation so
// we use a shared_ptr to manage it.
auto sp =
std::make_shared<boost::beast::http::message<false, boost::beast::http::string_body, boost::beast::http::fields>>(
std::move(res));
if (session_ == nullptr) {
throw std::runtime_error("session not valid");
}
// Store a type-erased version of the shared
// pointer in the class to keep it alive.
session_->res_ = sp;
// Write the response
boost::beast::http::async_write(session_->socket_, *sp,
std::bind(&Session::on_write, session_->shared_from_this(), sp->need_eof(),
std::placeholders::_1, std::placeholders::_2));
}
} // namespace expresscpp