userver: userver/server/handlers/http_handler_base.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
http_handler_base.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/server/handlers/http_handler_base.hpp
4/// @brief @copybrief server::handlers::HttpHandlerBase
5
6#include <optional>
7#include <string>
8#include <unordered_set>
9#include <vector>
10
11#include <userver/dynamic_config/source.hpp>
12#include <userver/logging/level.hpp>
13#include <userver/utils/statistics/entry.hpp>
14#include <userver/utils/token_bucket.hpp>
15
16#include <userver/server/handlers/auth/auth_checker_base.hpp>
17#include <userver/server/handlers/exceptions.hpp>
18#include <userver/server/handlers/formatted_error_data.hpp>
19#include <userver/server/handlers/handler_base.hpp>
20#include <userver/server/http/http_request.hpp>
21#include <userver/server/http/http_response.hpp>
22#include <userver/server/http/http_response_body_stream_fwd.hpp>
23#include <userver/server/request/request_base.hpp>
24#include <userver/tracing/span.hpp>
25
26USERVER_NAMESPACE_BEGIN
27
28namespace tracing {
30} // namespace tracing
31
32/// @brief Most common \ref userver_http_handlers "userver HTTP handlers"
33namespace server::handlers {
34
35class HttpHandlerStatistics;
36class HttpRequestStatistics;
37class HttpHandlerMethodStatistics;
38class HttpHandlerStatisticsScope;
39
40// clang-format off
41
42/// @ingroup userver_components userver_http_handlers userver_base_classes
43///
44/// @brief Base class for all the
45/// \ref userver_http_handlers "Userver HTTP Handlers".
46///
47/// ## Static options:
48/// Inherits all the options from server::handlers::HandlerBase and adds the
49/// following ones:
50///
51/// Name | Description | Default value
52/// ---- | ----------- | -------------
53/// log-level | overrides log level for this handle | <no override>
54/// status-codes-log-level | map of "status": log_level items to override span log level for specific status codes | {}
55///
56/// ## Example usage:
57///
58/// @snippet samples/hello_service/hello_service.cpp Hello service sample - component
59
60// clang-format on
61
63 public:
64 HttpHandlerBase(const components::ComponentConfig& config,
65 const components::ComponentContext& component_context,
66 bool is_monitor = false);
67
68 ~HttpHandlerBase() override;
69
71 request::RequestContext& context) const override;
72
73 void ReportMalformedRequest(request::RequestBase& request) const final;
74
75 virtual const std::string& HandlerName() const;
76
77 const std::vector<http::HttpMethod>& GetAllowedMethods() const;
78
79 /// @cond
80 // For internal use only.
81 HttpHandlerStatistics& GetHandlerStatistics() const;
82
83 // For internal use only.
84 HttpRequestStatistics& GetRequestStatistics() const;
85 /// @endcond
86
87 /// Override it if you need a custom logging level for messages about finish
88 /// of request handling for some http statuses.
90 http::HttpStatus status) const;
91
92 virtual FormattedErrorData GetFormattedExternalErrorBody(
93 const CustomHandlerException& exc) const;
94
95 std::string GetResponseDataForLoggingChecked(
96 const http::HttpRequest& request, request::RequestContext& context,
97 const std::string& response_data) const;
98
99 static yaml_config::Schema GetStaticConfigSchema();
100
101 protected:
102 [[noreturn]] void ThrowUnsupportedHttpMethod(
103 const http::HttpRequest& request) const;
104
105 /// The core method for HTTP request handling.
106 /// `request` arg contains HTTP headers, full body, etc.
107 /// The method should return response body.
108 /// @note It is used only if IsStreamed() returned `false`.
109 virtual std::string HandleRequestThrow(
110 const http::HttpRequest& request, request::RequestContext& context) const;
111
112 virtual void OnRequestCompleteThrow(
113 const http::HttpRequest& /*request*/,
114 request::RequestContext& /*context*/) const {}
115
116 /// The core method for HTTP request handling.
117 /// `request` arg contains HTTP headers, full body, etc.
118 /// The response body is passed in parts to `ResponseBodyStream`.
119 /// Stream transmission is useful when:
120 /// 1) The body size is unknown beforehand.
121 /// 2) The client may take advantage of early body transmission
122 /// (e.g. a Web Browser may start rendering the HTML page
123 /// or downloading dependant resources).
124 /// 3) The body size is huge and we want to have only a part of it
125 /// in memory.
126 /// @note It is used only if IsStreamed() returned `true`.
127 virtual void HandleStreamRequest(const server::http::HttpRequest&,
128 server::request::RequestContext&,
129 server::http::ResponseBodyStream&) const;
130
131 /// If IsStreamed() returns `true`, call HandleStreamRequest()
132 /// for request handling, HandleRequestThrow() is not called.
133 /// If it returns `false`, HandleRequestThrow() is called instead,
134 /// and HandleStreamRequest() is not called.
135 /// @note The default implementation returns the cached value of
136 /// "response-body-streamed" value from static config.
137 virtual bool IsStreamed() const { return is_body_streamed_; }
138
139 /// Override it to show per HTTP-method statistics besides statistics for all
140 /// methods
141 virtual bool IsMethodStatisticIncluded() const { return false; }
142
143 /// Override it if you want to disable auth checks in handler by some
144 /// condition
145 virtual bool NeedCheckAuth() const { return true; }
146
147 /// Override it if you need a custom request body logging.
148 virtual std::string GetRequestBodyForLogging(
149 const http::HttpRequest& request, request::RequestContext& context,
150 const std::string& request_body) const;
151
152 /// Override it if you need a custom response data logging.
153 virtual std::string GetResponseDataForLogging(
154 const http::HttpRequest& request, request::RequestContext& context,
155 const std::string& response_data) const;
156
157 /// For internal use. You don't need to override it. This method is overridden
158 /// in format-specific base handlers.
159 virtual void ParseRequestData(const http::HttpRequest&,
160 request::RequestContext&) const {}
161
162 virtual std::string GetMetaType(const http::HttpRequest&) const;
163
164 private:
165 void HandleRequestStream(const http::HttpRequest& http_request,
166 request::RequestContext& context) const;
167
168 std::string GetRequestBodyForLoggingChecked(
169 const http::HttpRequest& request, request::RequestContext& context,
170 const std::string& request_body) const;
171
172 tracing::Span MakeSpan(const http::HttpRequest& http_request,
173 const std::string& meta_type) const;
174
175 void CheckAuth(const http::HttpRequest& http_request,
176 request::RequestContext& context,
177 const dynamic_config::Snapshot& initial_config) const;
178
179 void CheckRatelimit(const http::HttpRequest& http_request) const;
180
181 void DecompressRequestBody(http::HttpRequest& http_request) const;
182
183 template <typename HttpStatistics>
184 void FormatStatistics(utils::statistics::Writer result,
185 const HttpStatistics& stats);
186
187 void SetResponseAcceptEncoding(http::HttpResponse& response) const;
188 void SetResponseServerHostname(http::HttpResponse& response) const;
189
190 const dynamic_config::Source config_source_;
191 const std::vector<http::HttpMethod> allowed_methods_;
192 const std::string handler_name_;
193 utils::statistics::Entry statistics_holder_;
194 const tracing::TracingManagerBase& tracing_manager_;
195 std::unordered_map<int, logging::Level> log_level_for_status_codes_;
196
197 std::unique_ptr<HttpHandlerStatistics> handler_statistics_;
198 std::unique_ptr<HttpRequestStatistics> request_statistics_;
199 std::vector<auth::AuthCheckerBasePtr> auth_checkers_;
200
201 std::optional<logging::Level> log_level_;
202 bool set_response_server_hostname_;
203 mutable utils::TokenBucket rate_limit_;
204 bool is_body_streamed_;
205};
206
207} // namespace server::handlers
208
209USERVER_NAMESPACE_END