Skip to content

Commit d1356ef

Browse files
committed
feat server: allow request body moving out
commit_hash:86bcb7d10acf464a468c10b2c04916403585eda0
1 parent dfb20c9 commit d1356ef

File tree

34 files changed

+64
-72
lines changed

34 files changed

+64
-72
lines changed

core/functional_tests/basic_chaos/httpclient_handlers.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class StreamHandler : public server::handlers::HttpHandlerBase {
6868

6969
/// [HandleStreamRequest]
7070
void HandleStreamRequest(
71-
const server::http::HttpRequest& request,
71+
server::http::HttpRequest& request,
7272
server::request::RequestContext&,
7373
server::http::ResponseBodyStream& response_body_stream
7474
) const override {

core/functional_tests/http2server/service.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class HandlerHttp2 final : public server::handlers::HttpHandlerBase {
3636
};
3737

3838
void HandleStreamRequest(
39-
const server::http::HttpRequest& req,
39+
server::http::HttpRequest& req,
4040
server::request::RequestContext&,
4141
server::http::ResponseBodyStream& stream
4242
) const override {

core/include/userver/server/handlers/handler_base.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class HandlerBase : public components::ComponentBase {
5757

5858
/// Parses request, executes processing routines, and fills response
5959
/// accordingly. Does not throw.
60-
virtual void HandleRequest(http::HttpRequest& request, request::RequestContext& context) const = 0;
60+
virtual void PrepareAndHandleRequest(http::HttpRequest& request, request::RequestContext& context) const = 0;
6161

6262
/// Produces response to a request unrecognized by the protocol based on
6363
/// provided generic response. Does not throw.

core/include/userver/server/handlers/http_handler_base.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class HttpHandlerBase : public HandlerBase {
7272

7373
~HttpHandlerBase() override;
7474

75-
void HandleRequest(http::HttpRequest& request, request::RequestContext& context) const override;
75+
void PrepareAndHandleRequest(http::HttpRequest& request, request::RequestContext& context) const override;
7676

7777
void ReportMalformedRequest(http::HttpRequest& request) const final;
7878

@@ -119,11 +119,14 @@ class HttpHandlerBase : public HandlerBase {
119119
protected:
120120
[[noreturn]] void ThrowUnsupportedHttpMethod(const http::HttpRequest& request) const;
121121

122+
/// Same as `HandleRequest`.
123+
virtual std::string HandleRequestThrow(const http::HttpRequest& request, request::RequestContext& context) const;
124+
122125
/// The core method for HTTP request handling.
123126
/// `request` arg contains HTTP headers, full body, etc.
124127
/// The method should return response body.
125128
/// @note It is used only if IsStreamed() returned `false`.
126-
virtual std::string HandleRequestThrow(const http::HttpRequest& request, request::RequestContext& context) const;
129+
virtual std::string HandleRequest(http::HttpRequest& request, request::RequestContext& context) const;
127130

128131
/// The core method for HTTP request handling.
129132
/// `request` arg contains HTTP headers, full body, etc.
@@ -137,12 +140,12 @@ class HttpHandlerBase : public HandlerBase {
137140
/// in memory.
138141
/// @note It is used only if IsStreamed() returned `true`.
139142
virtual void
140-
HandleStreamRequest(const server::http::HttpRequest&, server::request::RequestContext&, server::http::ResponseBodyStream&)
143+
HandleStreamRequest(server::http::HttpRequest&, server::request::RequestContext&, server::http::ResponseBodyStream&)
141144
const;
142145

143146
/// If IsStreamed() returns `true`, call HandleStreamRequest()
144-
/// for request handling, HandleRequestThrow() is not called.
145-
/// If it returns `false`, HandleRequestThrow() is called instead,
147+
/// for request handling, HandleRequest() is not called.
148+
/// If it returns `false`, HandleRequest() is called instead,
146149
/// and HandleStreamRequest() is not called.
147150
/// @note The default implementation returns the cached value of
148151
/// "response-body-streamed" value from static config.
@@ -182,7 +185,7 @@ class HttpHandlerBase : public HandlerBase {
182185

183186
void HandleHttpRequest(http::HttpRequest& request, request::RequestContext& context) const;
184187

185-
void HandleRequestStream(const http::HttpRequest& http_request, request::RequestContext& context) const;
188+
void HandleRequestStream(http::HttpRequest& http_request, request::RequestContext& context) const;
186189

187190
std::string GetRequestBodyForLoggingChecked(
188191
const http::HttpRequest& request,

core/include/userver/server/http/http_request.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ class HttpRequest final {
207207
/// @return HTTP body.
208208
const std::string& RequestBody() const;
209209

210+
/// @return moved out HTTP body. `this` is modified.
211+
std::string ExtractRequestBody();
212+
210213
/// @cond
211214
void SetRequestBody(std::string body);
212215
void ParseArgsFromBody();

core/src/server/handlers/http_handler_base.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ HttpHandlerBase::HttpHandlerBase(
198198

199199
HttpHandlerBase::~HttpHandlerBase() { statistics_holder_.Unregister(); }
200200

201-
void HttpHandlerBase::HandleRequestStream(const http::HttpRequest& http_request, request::RequestContext& context)
202-
const {
201+
void HttpHandlerBase::HandleRequestStream(http::HttpRequest& http_request, request::RequestContext& context) const {
203202
auto& response = http_request.GetHttpResponse();
204203
const utils::ScopeGuard scope([&response] { response.SetHeadersEnd(); });
205204

@@ -254,11 +253,11 @@ void HttpHandlerBase::HandleHttpRequest(http::HttpRequest& http_request, request
254253
HandleRequestStream(http_request, context);
255254
} else {
256255
// !IsBodyStreamed()
257-
response.SetData(HandleRequestThrow(http_request, context));
256+
response.SetData(HandleRequest(http_request, context));
258257
}
259258
}
260259

261-
void HttpHandlerBase::HandleRequest(http::HttpRequest& http_request, request::RequestContext& context) const {
260+
void HttpHandlerBase::PrepareAndHandleRequest(http::HttpRequest& http_request, request::RequestContext& context) const {
262261
auto& response = http_request.GetHttpResponse();
263262

264263
context.GetInternalContext().SetConfigSnapshot(config_source_.GetSnapshot());
@@ -288,13 +287,18 @@ void HttpHandlerBase::ThrowUnsupportedHttpMethod(const http::HttpRequest& reques
288287

289288
std::string HttpHandlerBase::HandleRequestThrow(const http::HttpRequest&, request::RequestContext&) const {
290289
throw std::runtime_error(
291-
"non-stream HandleRequestThrow() is executed, but the handler doesn't "
292-
"override HandleRequestThrow()."
290+
"non-stream HandleRequest() is executed, but the handler doesn't "
291+
"override HandleRequest()."
293292
);
294293
}
295294

295+
std::string HttpHandlerBase::HandleRequest(http::HttpRequest& request, request::RequestContext& context) const {
296+
// Default implementation proxies the request to legacy HandleRequestThrow()
297+
return HandleRequestThrow(request, context);
298+
}
299+
296300
void HttpHandlerBase::
297-
HandleStreamRequest(const server::http::HttpRequest&, server::request::RequestContext&, server::http::ResponseBodyStream&)
301+
HandleStreamRequest(server::http::HttpRequest&, server::request::RequestContext&, server::http::ResponseBodyStream&)
298302
const {
299303
throw std::runtime_error(
300304
"stream HandleStreamRequest() is executed, but the handler doesn't "

core/src/server/http/http_request.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ const HttpRequest::CookiesMap& HttpRequest::RequestCookies() const { return pimp
227227

228228
const std::string& HttpRequest::RequestBody() const { return pimpl_->request_body_; }
229229

230+
std::string HttpRequest::ExtractRequestBody() { return std::move(pimpl_->request_body_); }
231+
230232
void HttpRequest::SetRequestBody(std::string body) { pimpl_->request_body_ = std::move(body); }
231233

232234
void HttpRequest::ParseArgsFromBody() {

core/src/server/http/http_request_handler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ engine::TaskWithResult<void> HttpRequestHandler::StartRequestTask(std::shared_pt
153153
request->SetTaskStartTime();
154154

155155
request::RequestContext context;
156-
handler->HandleRequest(*request, context);
156+
handler->PrepareAndHandleRequest(*request, context);
157157

158158
const auto now = std::chrono::steady_clock::now();
159159
request->SetResponseNotifyTime(now);

samples/chaotic_service/src/hello_service.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ class Hello final : public server::handlers::HttpHandlerBase {
1919
using HttpHandlerBase::HttpHandlerBase;
2020

2121
/// [Handler]
22-
std::string HandleRequestThrow(const server::http::HttpRequest& request, server::request::RequestContext&)
23-
const override {
22+
std::string HandleRequest(server::http::HttpRequest& request, server::request::RequestContext&) const override {
2423
request.GetHttpResponse().SetContentType(http::content_type::kApplicationJson);
2524

2625
auto request_json = formats::json::FromString(request.RequestBody());

samples/clickhouse_service/clickhouse_service.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class HandlerDb final : public server::handlers::HttpHandlerBase {
3434

3535
HandlerDb(const components::ComponentConfig& config, const components::ComponentContext& context);
3636

37-
std::string HandleRequestThrow(const server::http::HttpRequest& request, server::request::RequestContext& context)
37+
std::string HandleRequest(server::http::HttpRequest& request, server::request::RequestContext& context)
3838
const override;
3939

4040
private:
@@ -45,8 +45,7 @@ HandlerDb::HandlerDb(const components::ComponentConfig& config, const components
4545
: server::handlers::HttpHandlerBase{config, context},
4646
clickhouse_{context.FindComponent<components::ClickHouse>("clickhouse-database").GetCluster()} {}
4747

48-
std::string HandlerDb::HandleRequestThrow(const server::http::HttpRequest& request, server::request::RequestContext&)
49-
const {
48+
std::string HandlerDb::HandleRequest(server::http::HttpRequest& request, server::request::RequestContext&) const {
5049
const auto& limit = request.GetArg("limit");
5150
// FP?: pfr magic
5251
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)

0 commit comments

Comments
 (0)