blob: 893ca18b4beb0a1604a3855c3f8d71e118ffac47 [file] [log] [blame]
#pragma once
#include "subscription.h"
#include <boost/beast/http/message.hpp>
#include <boost/beast/http/string_body.hpp>
#include <nlohmann/json.hpp>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
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;
nlohmann::json jsonValue;
// Identifiers for redfish event sources.
// Used in event subscription sequence only.
std::vector<ecclesia::EventSourceId> eventSourceIds;
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;
}
~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;
bool completed = false;
std::function<void(Response&)> completeRequestHandler;
std::map<std::string, int64_t> markers;
std::function<bool()> isAliveHelper;
};
} // namespace crow