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 =
 
   40template <
typename InputType, 
typename ReturnType>
 
   43                "Input type should be auto-generated FlatBuffers table type");
 
   45                "Return type should be auto-generated FlatBuffers table type");
 
   48  HttpHandlerFlatbufBase(
const components::ComponentConfig& config,
 
   49                         const components::ComponentContext& component_context);
 
   52                                 request::RequestContext& context) 
const final;
 
   54  virtual typename ReturnType::NativeTableType HandleRequestFlatbufThrow(
 
   55      const http::HttpRequest& request,
 
   56      const typename InputType::NativeTableType& input,
 
   57      request::RequestContext& context) 
const = 0;
 
   62      const request::RequestContext& context) 
const;
 
   67      const request::RequestContext& context) 
const;
 
   74      const http::HttpRequest& request, 
request::RequestContext& context,
 
   75      const std::string& request_body) 
const override;
 
   79      const http::HttpRequest& request, 
request::RequestContext& context,
 
   80      const std::string& response_data) 
const override;
 
   83                        request::RequestContext& context) 
const final;
 
   86template <
typename InputType, 
typename ReturnType>
 
   89    const components::ComponentContext& component_context)
 
   92template <
typename InputType, 
typename ReturnType>
 
   94    const http::HttpRequest& request, 
request::RequestContext& context) 
const {
 
   96      context.GetData<
const typename InputType::NativeTableType&>(
 
   97          impl::kFlatbufRequestDataName);
 
  100      context.SetData(std::string{impl::kFlatbufResponseDataName},
 
  101                      HandleRequestFlatbufThrow(request, input, context));
 
  103  flatbuffers::FlatBufferBuilder fbb;
 
  104  auto ret_fbb = ReturnType::Pack(fbb, &ret);
 
  106  return {
reinterpret_cast<
const char*>(fbb.GetBufferPointer()), fbb.GetSize()};
 
  109template <
typename InputType, 
typename ReturnType>
 
  112    const request::RequestContext& context) 
const {
 
  113  return context.GetDataOptional<
const typename InputType::NativeTableType>(
 
  114      impl::kFlatbufRequestDataName);
 
  117template <
typename InputType, 
typename ReturnType>
 
  120    const request::RequestContext& context) 
const {
 
  121  return context.GetDataOptional<
const typename ReturnType::NativeTableType>(
 
  122      impl::kFlatbufResponseDataName);
 
  125template <
typename InputType, 
typename ReturnType>
 
  128    const http::HttpRequest&, 
request::RequestContext&,
 
  129    const std::string& request_body) 
const {
 
  130  size_t limit = GetConfig().request_body_size_log_limit;
 
  131  return utils::log::ToLimitedHex(request_body, limit);
 
  134template <
typename InputType, 
typename ReturnType>
 
  137    const http::HttpRequest&, 
request::RequestContext&,
 
  138    const std::string& response_data) 
const {
 
  139  size_t limit = GetConfig().response_data_size_log_limit;
 
  140  return utils::log::ToLimitedHex(response_data, limit);
 
  143template <
typename InputType, 
typename ReturnType>
 
  145    const http::HttpRequest& request, 
request::RequestContext& context) 
const {
 
  147  const auto* input_fbb = flatbuffers::GetRoot<InputType>(body.data());
 
  148  flatbuffers::Verifier verifier(
reinterpret_cast<
const uint8_t*>(body.data()),
 
  150  if (!input_fbb->Verify(verifier)) {
 
  152        InternalMessage{
"Invalid FlatBuffers format in request body"});
 
  155  typename InputType::NativeTableType input;
 
  156  input_fbb->UnPackTo(&input);
 
  158  context.SetData(std::string{impl::kFlatbufRequestDataName}, std::move(input));
 
  161template <
typename InputType, 
typename ReturnType>
 
  165  schema.UpdateDescription(
"HTTP handler flatbuf base config");