blob: 7fa672e2e8be23a6b0ca796ffc56957ebf289b61 [file] [log] [blame]
#ifndef THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_
#define THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_
#include <cstdint>
#include <functional>
#include <map>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "boost/beast/http/message.hpp" // NOLINT
#include "boost/beast/http/string_body.hpp" // NOLINT
#include "subscription.h"
#include <nlohmann/json.hpp>
namespace crow {
template <typename Adaptor, typename Handler>
class Connection;
struct Response {
template <typename Adaptor, typename Handler>
friend class crow::Connection;
using response_type =
boost::beast::http::response<boost::beast::http::string_body>;
std::optional<response_type> stringResponse; // NOLINT
nlohmann::json jsonValue; // NOLINT
// Identifiers for redfish event sources.
// Used in event subscription sequence only.
std::vector<ecclesia::EventSourceId> eventSourceIds; // NOLINT
void addHeader(std::string_view key, std::string_view value) {
stringResponse->set(key, value);
}
void addHeader(boost::beast::http::field key, std::string_view value) {
stringResponse->set(key, value);
}
Response() : stringResponse(response_type{}) {}
Response(Response&& res) noexcept
: stringResponse(std::move(res.stringResponse)),
jsonValue(std::move(res.jsonValue)),
completed(res.completed) {
// See note in operator= move handler for why this is needed.
if (!res.completed) {
completeRequestHandler = std::move(res.completeRequestHandler);
res.completeRequestHandler = nullptr;
}
isAliveHelper = res.isAliveHelper;
res.isAliveHelper = nullptr;
}
virtual ~Response() = default;
Response(const Response&) = delete;
Response& operator=(const Response& r) = delete;
Response& operator=(Response&& r) noexcept;
void result(unsigned v) { stringResponse->result(v); }
void result(boost::beast::http::status v) { stringResponse->result(v); }
boost::beast::http::status result() const { return stringResponse->result(); }
unsigned resultInt() const { return stringResponse->result_int(); }
std::string_view reason() const { return stringResponse->reason(); }
bool isCompleted() const noexcept { return completed; }
std::string& body() { return stringResponse->body(); }
std::string_view getHeaderValue(std::string_view key) const {
return stringResponse->base()[key];
}
void keepAlive(bool k) { stringResponse->keep_alive(k); }
bool keepAlive() const { return stringResponse->keep_alive(); }
void preparePayload() { stringResponse->prepare_payload(); }
void clear();
void write(std::string_view bodyPart) {
stringResponse->body() += std::string(bodyPart);
}
std::string computeEtag() const;
void end();
bool isAlive() const { return isAliveHelper && isAliveHelper(); }
void setCompleteRequestHandler(std::function<void(Response&)>&& handler);
std::function<void(Response&)> releaseCompleteRequestHandler();
void setIsAliveHelper(std::function<bool()>&& handler) {
isAliveHelper = std::move(handler);
}
std::function<bool()> releaseIsAliveHelper() {
std::function<bool()> ret = std::move(isAliveHelper);
isAliveHelper = nullptr;
return ret;
}
void setHashAndHandleNotModified();
void setExpectedHash(std::string_view hash) { expectedHash = hash; }
void startTimetrace(const std::string& block);
void endTimetrace(const std::string& block);
void requestStartTime(const std::string& uri);
void requestEndTime();
nlohmann::json timetraceToJson();
void updateTraceInManagedStore();
private:
void addTimetrace(const std::string& marker);
std::optional<std::string> expectedHash; // NOLINT
bool completed = false;
std::function<void(Response&)> completeRequestHandler; // NOLINT
std::map<std::string, int64_t> markers;
std::function<bool()> isAliveHelper; // NOLINT
};
} // namespace crow
#endif // THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_