11 std::shared_ptr<hpack_encoder> encoder,
14 : stream_id_(stream_id)
15 , request_(std::move(request))
16 , encoder_(std::move(encoder))
17 , frame_sender_(std::move(frame_sender))
23 const std::vector<http_header>&
headers,
26 std::lock_guard<std::mutex> lock(mutex_);
32 "Stream is closed for sending",
33 "http2_server_stream");
39 "Headers already sent",
40 "http2_server_stream");
44 auto response_headers = build_response_headers(status_code,
headers);
47 auto encoded = encoder_->encode(response_headers);
51 auto result = frame_sender_(
frame);
53 if (result.is_err()) {
69 std::lock_guard<std::mutex> lock(mutex_);
75 "Stream is closed for sending",
76 "http2_server_stream");
82 "Headers must be sent before data",
83 "http2_server_stream");
88 while (offset <
data.size()) {
89 size_t chunk_size = std::min(
90 static_cast<size_t>(max_frame_size_),
91 data.size() - offset);
93 std::vector<uint8_t> chunk(
data.begin() +
static_cast<std::ptrdiff_t
>(offset),
94 data.begin() +
static_cast<std::ptrdiff_t
>(offset + chunk_size));
96 bool is_last = (offset + chunk_size >=
data.size());
97 bool frame_end_stream = end_stream && is_last;
100 auto result = frame_sender_(
frame);
102 if (result.is_err()) {
106 offset += chunk_size;
110 if (
data.empty() && end_stream) {
112 auto result = frame_sender_(
frame);
113 if (result.is_err()) {
127 std::vector<uint8_t> bytes(
data.begin(),
data.end());
128 return send_data(bytes, end_stream);
134 return send_headers(status_code,
headers,
false);
139 return send_data(chunk,
false);
144 return send_data(std::vector<uint8_t>{},
true);
149 std::lock_guard<std::mutex> lock(mutex_);
156 auto result = frame_sender_(
frame);
190 std::lock_guard<std::mutex> lock(
mutex_);
197 std::lock_guard<std::mutex> lock(
mutex_);
203 std::lock_guard<std::mutex> lock(
mutex_);
209 std::lock_guard<std::mutex> lock(mutex_);
210 window_size_ += increment;
215 std::lock_guard<std::mutex> lock(
mutex_);
220 const std::vector<http_header>& additional)
221 -> std::vector<http_header>
223 std::vector<http_header>
headers;
224 headers.reserve(additional.size() + 1);
227 headers.emplace_back(
":status", std::to_string(status_code));
230 for (
const auto& header : additional) {
DATA frame (RFC 7540 Section 6.1)
Base class for HTTP/2 frames.
auto headers_sent() const -> bool
Check if headers have been sent.
auto state() const -> stream_state
Get current stream state.
stream_state state_
Current stream state.
std::function< VoidResult(const frame &)> frame_sender_t
Function type for sending frames.
auto method() const -> std::string_view
Get request method.
auto send_headers(int status_code, const std::vector< http_header > &headers, bool end_stream=false) -> VoidResult
Send response headers.
auto is_open() const -> bool
Check if stream is open for sending.
auto start_response(int status_code, const std::vector< http_header > &headers) -> VoidResult
Start a streaming response.
bool headers_sent_
Headers have been sent.
uint32_t stream_id_
Stream identifier.
auto path() const -> std::string_view
Get request path.
auto reset(uint32_t err_code=static_cast< uint32_t >(error_code::cancel)) -> VoidResult
Reset the stream with an error code.
auto build_response_headers(int status_code, const std::vector< http_header > &additional) -> std::vector< http_header >
Build response headers with :status pseudo-header.
auto send_data(const std::vector< uint8_t > &data, bool end_stream=false) -> VoidResult
Send response data.
auto end_response() -> VoidResult
End the streaming response.
auto headers() const -> const std::vector< http_header > &
Get request headers.
http2_server_stream(uint32_t stream_id, http2_request request, std::shared_ptr< hpack_encoder > encoder, frame_sender_t frame_sender, uint32_t max_frame_size=16384)
Construct server stream.
auto request() const -> const http2_request &
Get the full request.
std::mutex mutex_
State protection mutex.
int32_t window_size_
Flow control window.
auto stream_id() const -> uint32_t
Get stream identifier.
auto write(const std::vector< uint8_t > &chunk) -> VoidResult
Write data chunk for streaming response.
auto update_window(int32_t increment) -> void
Update flow control window.
http2_request request_
Original request.
auto window_size() const -> int32_t
Get available window size.
RST_STREAM frame (RFC 7540 Section 6.4)
constexpr int invalid_argument
@ max_frame_size
SETTINGS_MAX_FRAME_SIZE.
stream_state
HTTP/2 stream state (RFC 7540 Section 5.1)
@ closed
Stream fully closed.
@ open
Stream open and active.
@ half_closed_remote
Remote end closed, local can send.
@ half_closed_local
Local end closed, remote can send.
VoidResult error_void(int code, const std::string &message, const std::string &source="network_system", const std::string &details="")
HTTP/2 request data structure.
std::string path
Request path (:path pseudo-header)
std::vector< http_header > headers
Regular headers (non-pseudo)
std::string method
HTTP method (:method pseudo-header)