userver: HTTP, HTTPS, WebSocket
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
HTTP, HTTPS, WebSocket

Your opinion will help to improve our service

Leave a feedback >

Quality:

Introduction

🐙 userver implements HTTP/HTTPS 1.1, HTTP 2.0 and WebSocket server in userver-core library using components::Server component.

Capabilities

Streaming API

Interactive clients (e.g. web browser) might want to get at least first bytes of the HTTP response if the whole HTTP response is generated slowly. In this case the HTTP handler might want to use Streaming API and return HTTP response body as a byte stream rather than as a single-part blob.

To enable Streaming API in your handler:

1) define HandleStreamRequest() method:

#include <userver/server/http/http_response_body_stream_fwd.hpp>
...
void HandleStreamRequest(server::http::HttpRequest&,

2) Enable Streaming API in static config:

components_manager:
components:
handler-stream-api:
response-body-stream: true

3) Write your handler code:

void HandleStreamRequest(
server::http::HttpRequest& request,
server::request::RequestContext&,
server::http::ResponseBodyStream& response_body_stream
) const override {
for (const auto& header_name : request.GetHeaderNames()) {
const auto& header_value = request.GetHeader(header_name);
headers[header_name] = header_value;
}
const auto& port = request.GetArg("port");
auto url = fmt::format("http://localhost:{}/test", port);
const auto& timeout_string = request.GetArg("timeout");
const auto timeout = timeout_string.empty() ? kDefaultTimeout : std::chrono::seconds{std::stoi(timeout_string)};
const auto retries = 1;
auto external_request =
http_client_.CreateRequest().get(url).headers(std::move(headers)).timeout(timeout).retry(retries);
auto client_response = external_request.async_perform_stream_body(std::move(queue));
TESTPOINT("stream_after_start", {});
for (const auto& header_item : client_response.GetHeaders()) {
TESTPOINT("stream_after_get_headers", {});
const auto& header_name = header_item.first;
const auto& header_value = header_item.second;
response_body_stream.SetHeader(header_name, header_value);
}
auto status_code = client_response.StatusCode();
response_body_stream.SetStatusCode(status_code);
response_body_stream.SetHeader(std::string{"abc"}, std::string{"def"});
response_body_stream.SetEndOfHeaders();
TESTPOINT("stream_after_set_end_of_headers", {});
std::string body_part;
auto deadline = engine::Deadline::FromDuration(std::chrono::seconds(10));
while (client_response.ReadChunk(body_part, deadline)) {
TESTPOINT("stream_after_read_chunk", {});
response_body_stream.PushBodyChunk(std::move(body_part), engine::Deadline());
TESTPOINT("stream_after_push_body_chunk", {});
}
}

HTTP version

The HTTP server in userver supports versions 1.1 and 2.0. The default version is 1.1. You can enable version 2.0 in the static config such as:

components_manager:
    components:
        # ... other components
        server:
            listener:
                port: 8080
                task_processor: main-task-processor
                connection:
                    http-version: '2' # enum `1.1` or `2`
                    http2-session:
                        max_concurrent_streams: 100
                        max_frame_size: 16384
                        initial_window_size: 65536

You can set some options specific to HTTP/2.0 in the http2-session section. See docs for these options in components::Server

Components