8#include <flatbuffers/flatbuffers.h>
10#include <userver/server/handlers/http_handler_base.hpp>
11#include <userver/server/http/http_error.hpp>
12#include <userver/utils/log.hpp>
13#include <userver/yaml_config/schema.hpp>
15USERVER_NAMESPACE_BEGIN
17namespace server::handlers {
21inline constexpr std::string_view kFlatbufRequestDataName =
"__request_flatbuf";
22inline constexpr std::string_view kFlatbufResponseDataName =
"__response_flatbuf";
39template <
typename InputType,
typename ReturnType>
43 "Input type should be auto-generated FlatBuffers table type"
47 "Return type should be auto-generated FlatBuffers table type"
51 HttpHandlerFlatbufBase(
53 const components::ComponentContext& component_context
58 virtual typename ReturnType::NativeTableType HandleRequestFlatbufThrow(
59 const http::HttpRequest& request,
60 const typename InputType::NativeTableType& input,
61 request::RequestContext& context
77 const http::HttpRequest& request,
78 request::RequestContext& context,
79 const std::string& request_body
84 const http::HttpRequest& request,
85 request::RequestContext& context,
86 const std::string& response_data
92template <
typename InputType,
typename ReturnType>
95 const components::ComponentContext& component_context
99template <
typename InputType,
typename ReturnType>
101 const http::HttpRequest& request,
102 request::RequestContext& context
104 const auto& input = context.GetData<
const typename InputType::NativeTableType&>(impl::kFlatbufRequestDataName);
106 const auto& ret = context.SetData(
107 std::string{impl::kFlatbufResponseDataName}, HandleRequestFlatbufThrow(request, input, context)
110 flatbuffers::FlatBufferBuilder fbb;
111 auto ret_fbb = ReturnType::Pack(fbb, &ret);
113 return {
reinterpret_cast<
const char*>(fbb.GetBufferPointer()), fbb.GetSize()};
116template <
typename InputType,
typename ReturnType>
118 const request::RequestContext& context
120 return context.GetDataOptional<
const typename InputType::NativeTableType>(impl::kFlatbufRequestDataName);
123template <
typename InputType,
typename ReturnType>
125 const request::RequestContext& context
127 return context.GetDataOptional<
const typename ReturnType::NativeTableType>(impl::kFlatbufResponseDataName);
130template <
typename InputType,
typename ReturnType>
132 const http::HttpRequest&,
134 const std::string& request_body
136 size_t limit = GetConfig().request_body_size_log_limit;
137 return utils::log::ToLimitedHex(request_body, limit);
140template <
typename InputType,
typename ReturnType>
142 const http::HttpRequest&,
144 const std::string& response_data
146 size_t limit = GetConfig().response_data_size_log_limit;
147 return utils::log::ToLimitedHex(response_data, limit);
150template <
typename InputType,
typename ReturnType>
152 const http::HttpRequest& request,
153 request::RequestContext& context
156 const auto* input_fbb = flatbuffers::GetRoot<InputType>(body.data());
157 flatbuffers::Verifier verifier(
reinterpret_cast<
const uint8_t*>(body.data()), body.size());
158 if (!input_fbb->Verify(verifier)) {
159 throw ClientError(InternalMessage{
"Invalid FlatBuffers format in request body"});
162 typename InputType::NativeTableType input;
163 input_fbb->UnPackTo(&input);
165 context.SetData(std::string{impl::kFlatbufRequestDataName}, std::move(input));
168template <
typename InputType,
typename ReturnType>
171 schema.UpdateDescription(
"HTTP handler flatbuf base config");