A11 (C++ runtime)
Native C++ implementation of the A11 streaming action runtime
Loading...
Searching...
No Matches
http2.h
Go to the documentation of this file.
1/*
2 * Copyright 2026 The A11 Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
29#ifndef A11_NET_HTTP2_H_
30#define A11_NET_HTTP2_H_
31
32#include <cstddef>
33#include <cstdint>
34#include <functional>
35#include <memory>
36#include <optional>
37#include <string>
38#include <string_view>
39#include <utility>
40#include <vector>
41
42#include <absl/base/nullability.h>
43#include <absl/status/status.h>
44#include <absl/status/statusor.h>
45#include <absl/time/time.h>
46
48// For sizeof(thread::Mutex) in Http2Client's inline-storage budget below.
49#include "thread/boost_primitives.h"
50
51namespace a11::net {
52
55class HttpConnection;
56
57namespace internal {
59class HttpTransport;
60} // namespace internal
61
62class Http2RequestBodyStream;
63
70using HttpHeaders = std::vector<std::pair<std::string, std::string>>;
71
73void NormalizeHttpHeaders(HttpHeaders* absl_nonnull headers);
75std::optional<std::string> GetHttpHeader(const HttpHeaders& headers,
76 std::string_view name);
78void EraseHttpHeader(HttpHeaders* absl_nonnull headers, std::string_view name);
80void SetHttpHeader(HttpHeaders* absl_nonnull headers, std::string name,
81 std::string value);
83absl::Status ValidateHttpHeaders(const HttpHeaders& headers);
84
91 std::string method;
92 std::string protocol;
93 std::string scheme;
94 std::string authority;
95 std::string path;
97 std::string body;
99 std::shared_ptr<Http2RequestBodyStream> body_stream;
100};
101
107
111 std::string body = {};
112};
113
114class Http2ResponseStream;
115
126 std::string method;
127 std::string scheme;
128 std::string authority;
129 std::string path;
132 std::shared_ptr<Http2ResponseStream> response;
133};
134
138 bool enabled = false;
139 bool verify_peer = true;
141 std::string key_pem_file;
143
145 absl::Status Validate() const;
146};
147
153 kAuto,
154 kHttp2,
155 kHttp11,
156 };
157
158 size_t max_request_body_size = 32 * 1024 * 1024;
159 size_t max_response_body_size = 32 * 1024 * 1024;
161 4 * 1024 * 1024;
163 4 * 1024 * 1024;
164 absl::Time deadline = absl::InfiniteFuture();
166
167 // --- Protocol negotiation (server: which to accept; client: which to try).
168 // ---
169 bool enable_h2 = true;
170 bool enable_h2c = true;
171 bool enable_http1 = true;
180 bool enable_push = false;
186
205 std::function<bool(std::string_view method, std::string_view path,
206 const HttpHeaders& headers)>
208
210 absl::Status Validate() const;
211};
212
213class Http2Connection;
214
222 : public std::enable_shared_from_this<Http2RequestBodyStream> {
223 public:
228 a11::Task Done() const;
230 absl::Status Cancel(absl::Status status = absl::CancelledError(
231 "HTTP/2 request body cancelled"));
233 [[nodiscard]] std::int32_t stream_id() const;
234
235 private:
236 struct State;
237
238 explicit Http2RequestBodyStream(std::shared_ptr<State> state)
239 : state_(std::move(state)) {}
240
241 std::shared_ptr<State> state_;
242
243 friend class Http2Connection;
244 friend class Http1Connection;
245};
246
255 : public std::enable_shared_from_this<Http2ResponseStream> {
256 public:
286 a11::Task Done() const;
288 absl::Status Cancel(
289 absl::Status status = absl::CancelledError("HTTP/2 request cancelled"));
291 [[nodiscard]] std::int32_t stream_id() const;
292
293 private:
294 struct State;
295
296 explicit Http2ResponseStream(std::shared_ptr<State> state)
297 : state_(std::move(state)) {}
298
299 std::shared_ptr<State> state_;
300
301 friend class Http2Connection;
302 friend class Http1Connection;
303 friend class Http2Client;
304};
305
314 : public std::enable_shared_from_this<Http2DuplexStream> {
315 public:
322 absl::Status Write(std::string data);
324 absl::Status Finish();
326 absl::Status Abort(absl::Status status = absl::CancelledError(
327 "HTTP/2 duplex stream cancelled"));
329 a11::Task Done() const;
330
341 [[nodiscard]] const std::shared_ptr<Http2ResponseStream>& response() const {
342 return response_;
343 }
344
346 [[nodiscard]] std::int32_t stream_id() const;
347
348 private:
349 Http2DuplexStream(std::weak_ptr<HttpConnection> connection,
350 std::shared_ptr<Http2ResponseStream> response)
351 : connection_(std::move(connection)), response_(std::move(response)) {}
352
353 std::weak_ptr<HttpConnection> connection_;
354 std::shared_ptr<Http2ResponseStream> response_;
355
356 friend class Http2Connection;
357 friend class Http1Connection;
358 friend class Http2Client;
359};
360
369 : public std::enable_shared_from_this<Http2ResponseWriter> {
370 public:
372 absl::Status SendHeaders(int status, HttpHeaders headers = {});
374 absl::Status Write(std::string data);
376 absl::Status Finish();
383 absl::Status FinishWithTrailers(HttpHeaders trailers);
385 absl::Status SendResponse(int status, HttpHeaders headers = {},
386 std::string body = {});
402 absl::StatusOr<std::shared_ptr<Http2ResponseWriter>> PushPromise(
403 std::string method, std::string path, HttpHeaders headers = {});
405 absl::Status Abort(absl::Status status);
407 a11::Task Done() const;
408
418 void DeferResponse();
419
421 [[nodiscard]] bool response_deferred() const;
422
424 [[nodiscard]] bool headers_sent() const;
426 [[nodiscard]] bool finished() const;
427
429 [[nodiscard]] std::int32_t stream_id() const { return stream_id_; }
430
431 private:
432 struct State;
433
434 Http2ResponseWriter(std::weak_ptr<HttpConnection> connection,
435 std::int32_t stream_id, std::shared_ptr<State> state)
436 : connection_(std::move(connection)),
437 stream_id_(stream_id),
438 state_(std::move(state)) {}
439
440 std::weak_ptr<HttpConnection> connection_;
441 std::int32_t stream_id_;
442 std::shared_ptr<State> state_;
443
444 friend class Http2Connection;
445 friend class Http1Connection;
446};
447
449using Http2RequestHandler = std::function<a11::Task(
450 HttpRequest request, std::shared_ptr<Http2ResponseWriter> response)>;
451
458class Http2Server : public std::enable_shared_from_this<Http2Server> {
459 public:
469 static absl::StatusOr<std::shared_ptr<Http2Server>> Create(
470 std::string bind_address, std::uint16_t port, Http2RequestHandler handler,
471 const Http2Options& options = {});
472
473 ~Http2Server();
474
476 absl::Status Stop();
478 [[nodiscard]] std::uint16_t port() const;
480 [[nodiscard]] std::string bind_address() const;
482 [[nodiscard]] bool running() const;
484 [[nodiscard]] bool secure() const;
486 [[nodiscard]] void* absl_nullable GetImpl() const;
487
488 private:
489 struct State;
490
491 explicit Http2Server(std::shared_ptr<State> state)
492 : state_(std::move(state)) {}
493
494 std::shared_ptr<State> state_;
495};
496
504class Http2Client : public std::enable_shared_from_this<Http2Client> {
505 public:
515 std::string host, std::uint16_t port, const Http2Options& options = {});
516
517 ~Http2Client();
518
520 absl::StatusOr<std::shared_ptr<Http2ResponseStream>> RequestStream(
521 std::string method, std::string path, HttpHeaders headers = {},
522 std::string body = {}, std::string scheme = {});
524 absl::StatusOr<std::shared_ptr<Http2DuplexStream>> ExtendedConnect(
525 std::string protocol, std::string path, HttpHeaders headers = {},
526 std::string scheme = {});
543 absl::StatusOr<std::shared_ptr<Http2DuplexStream>> RequestStreamingBody(
544 std::string method, std::string path, HttpHeaders headers = {},
545 std::string scheme = {});
547 a11::Future<HttpResponse> Request(std::string method, std::string path,
548 HttpHeaders headers = {},
549 std::string body = {},
550 std::string scheme = {});
552 absl::Status Close();
553
555 [[nodiscard]] std::string host() const;
557 [[nodiscard]] std::uint16_t port() const;
559 [[nodiscard]] bool connected() const;
561 [[nodiscard]] bool secure() const;
569 [[nodiscard]] bool multiplexed() const;
571 [[nodiscard]] void* absl_nullable GetImpl() const;
572
573 private:
574 struct Impl;
575
576 // Inline storage for Impl, whose definition lives in the .cc.
577 static constexpr size_t kImplSize =
578 sizeof(std::string) + // host
579 sizeof(std::uint16_t) + // port
580 sizeof(Http2Options) + // options
581 sizeof(thread::Mutex) + // mu
582 sizeof(std::shared_ptr<internal::HttpTransport>) + // connection
583 32; // padding and slack
584 static constexpr size_t kImplAlignment = alignof(std::max_align_t);
585
586 Http2Client(std::string host, std::uint16_t port, const Http2Options& options,
587 std::shared_ptr<internal::HttpTransport> connection);
588
589 Impl* absl_nonnull state();
590 const Impl* absl_nonnull state() const;
591
592 alignas(kImplAlignment) std::byte impl_[kImplSize];
593};
594
595} // namespace a11::net
596
597#endif // A11_NET_HTTP2_H_
Shared handle to one asynchronous result.
Definition future.h:126
An HTTP/2 client connection, reusable across many streams.
Definition http2.h:504
std::string host() const
Definition http2.cc:2817
static a11::Future< std::shared_ptr< Http2Client > > Connect(std::string host, std::uint16_t port, const Http2Options &options={})
Asynchronously connects to an HTTP/2 server.
Definition http2.cc:2465
absl::StatusOr< std::shared_ptr< Http2DuplexStream > > RequestStreamingBody(std::string method, std::string path, HttpHeaders headers={}, std::string scheme={})
Opens a request whose body is written incrementally.
Definition http2.cc:2741
bool multiplexed() const
Whether this connection can carry several exchanges at once.
Definition http2.cc:2838
absl::Status Close()
Closes the client connection.
Definition http2.cc:2805
bool connected() const
Definition http2.cc:2825
absl::StatusOr< std::shared_ptr< Http2DuplexStream > > ExtendedConnect(std::string protocol, std::string path, HttpHeaders headers={}, std::string scheme={})
Opens an extended CONNECT duplex stream for bidirectional data.
Definition http2.cc:2714
void *absl_nullable GetImpl() const
Definition http2.cc:2849
a11::Future< HttpResponse > Request(std::string method, std::string path, HttpHeaders headers={}, std::string body={}, std::string scheme={})
Definition http2.cc:2766
bool secure() const
Definition http2.cc:2834
~Http2Client()
Definition http2.cc:2683
absl::StatusOr< std::shared_ptr< Http2ResponseStream > > RequestStream(std::string method, std::string path, HttpHeaders headers={}, std::string body={}, std::string scheme={})
Opens a request and returns a pull-oriented response body stream.
Definition http2.cc:2688
std::uint16_t port() const
Definition http2.cc:2821
Definition http2.cc:495
Client side of an HTTP/2 extended CONNECT stream.
Definition http2.h:314
a11::Future< HttpResponseHead > Headers() const
Definition http2.cc:2021
absl::Status Abort(absl::Status status=absl::CancelledError("HTTP/2 duplex stream cancelled"))
Aborts the whole duplex stream with the given status.
Definition http2.cc:2045
friend class Http1Connection
Definition http2.h:357
absl::Status Write(std::string data)
Writes a chunk of request DATA.
Definition http2.cc:2029
const std::shared_ptr< Http2ResponseStream > & response() const
The read half, for the parts of a response this facade does not forward.
Definition http2.h:341
absl::Status Finish()
Closes the request side, signalling END_STREAM to the peer.
Definition http2.cc:2037
a11::Task Done() const
Definition http2.cc:2049
std::int32_t stream_id() const
Definition http2.cc:2053
a11::Future< std::optional< std::string > > Read()
Definition http2.cc:2025
Pull-oriented request DATA for a request that stays open.
Definition http2.h:222
a11::Task Done() const
Definition http2.cc:248
friend class Http1Connection
Definition http2.h:244
absl::Status Cancel(absl::Status status=absl::CancelledError("HTTP/2 request body cancelled"))
Cancels the body stream with the given status.
Definition http2.cc:252
a11::Future< std::optional< std::string > > Read()
Definition http2.cc:210
std::int32_t stream_id() const
Definition http2.cc:271
A pull-oriented HTTP/2 response body stream.
Definition http2.h:255
a11::Task Done() const
Definition http2.cc:371
std::int32_t stream_id() const
Definition http2.cc:394
a11::Future< std::optional< std::string > > Read()
Definition http2.cc:280
a11::Future< HttpHeaders > Trailers() const
The trailer fields that followed the body.
Definition http2.cc:329
friend class Http1Connection
Definition http2.h:302
absl::Status Cancel(absl::Status status=absl::CancelledError("HTTP/2 request cancelled"))
Cancels the response stream with the given status.
Definition http2.cc:375
a11::Future< HttpResponseHead > Headers() const
Definition http2.cc:276
a11::Future< std::optional< HttpPushedResponse > > NextPush()
The next response the server pushed alongside this one.
Definition http2.cc:333
Server-side handle for writing an HTTP/2 response to one request.
Definition http2.h:369
std::int32_t stream_id() const
Definition http2.h:429
bool headers_sent() const
Definition http2.cc:2132
void DeferResponse()
Says this response will be sent after the handler returns.
Definition http2.cc:2124
absl::Status Finish()
Signals the end of the response body.
Definition http2.cc:2073
bool finished() const
Definition http2.cc:2141
bool response_deferred() const
Definition http2.cc:2128
absl::Status Write(std::string data)
Writes a chunk of response body data.
Definition http2.cc:2065
absl::Status SendHeaders(int status, HttpHeaders headers={})
Sends the response status and headers.
Definition http2.cc:2057
absl::Status Abort(absl::Status status)
Aborts the response with the given status.
Definition http2.cc:2110
friend class Http1Connection
Definition http2.h:445
absl::Status SendResponse(int status, HttpHeaders headers={}, std::string body={})
Sends a complete response (status, headers, and body) in one call.
Definition http2.cc:2100
absl::StatusOr< std::shared_ptr< Http2ResponseWriter > > PushPromise(std::string method, std::string path, HttpHeaders headers={})
Promises a response the client did not ask for (server push).
Definition http2.cc:2082
a11::Task Done() const
Definition http2.cc:2118
absl::Status FinishWithTrailers(HttpHeaders trailers)
Ends the response body with a trailer section.
Definition http2.cc:2092
An HTTP/2 server that dispatches each request to an async handler.
Definition http2.h:458
std::string bind_address() const
Definition http2.cc:2447
void *absl_nullable GetImpl() const
Definition http2.cc:2460
static absl::StatusOr< std::shared_ptr< Http2Server > > Create(std::string bind_address, std::uint16_t port, Http2RequestHandler handler, const Http2Options &options={})
Creates and starts an HTTP/2 server.
Definition http2.cc:2222
bool running() const
Definition http2.cc:2451
~Http2Server()
Definition http2.cc:2412
absl::Status Stop()
Stops the server and releases its resources.
Definition http2.cc:2416
std::uint16_t port() const
Definition http2.cc:2442
bool secure() const
Definition http2.cc:2456
std::string value
Definition discover.cc:114
std::string name
The name and its colon, which travel together because they always do.
Definition format.cc:49
Completion values used by every asynchronous A11 operation.
std::string path
Definition main.cc:133
Definition action.h:65
absl::Status ValidateHttpHeaders(const HttpHeaders &headers)
Definition http2.cc:432
std::vector< std::pair< std::string, std::string > > HttpHeaders
An ordered list of (name, value) HTTP/2 header fields.
Definition http2.h:70
void EraseHttpHeader(HttpHeaders *headers, std::string_view name)
Definition http2.cc:419
std::optional< std::string > GetHttpHeader(const HttpHeaders &headers, std::string_view name)
Definition http2.cc:406
void SetHttpHeader(HttpHeaders *headers, std::string name, std::string value)
Definition http2.cc:426
void NormalizeHttpHeaders(HttpHeaders *headers)
Definition http2.cc:399
std::function< a11::Task(HttpRequest request, std::shared_ptr< Http2ResponseWriter > response)> Http2RequestHandler
Callback dispatched for each inbound request, given a response writer.
Definition http2.h:450
Future< Unit > Task
Asynchronous operation whose only successful result is completion itself.
Definition future.h:411
std::string data
Definition sqlite_chunk_store.cc:192
Definition http2.cc:2645
Body-size limits, buffering thresholds, deadline, TLS, and HTTP protocol negotiation for an HTTP clie...
Definition http2.h:150
bool enable_h2
Serve/accept HTTP/2 over TLS (ALPN "h2").
Definition http2.h:169
bool enable_h2c
Serve/accept cleartext prior-knowledge HTTP/2.
Definition http2.h:170
size_t max_response_body_size
Response hard limit.
Definition http2.h:159
size_t max_buffered_request_bytes
Request backpressure bound.
Definition http2.h:160
Http2TlsOptions tls
TLS and certificate policy.
Definition http2.h:165
bool client_allow_downgrade
Whether a cleartext client may reconnect with the other protocol when its first attempt fails (ALPN m...
Definition http2.h:185
ProtocolPreference client_preference
Client protocol preference; also governs cleartext attempt order.
Definition http2.h:182
ProtocolPreference
Client-side HTTP protocol preference / downgrade policy.
Definition http2.h:152
@ kHttp2
Require HTTP/2 (h2 over TLS, prior-knowledge h2c cleartext).
@ kAuto
Prefer HTTP/2, fall back to HTTP/1.1 (ALPN order / downgrade).
absl::Status Validate() const
Validate size relationships, deadline, TLS, and protocol settings.
Definition http2.cc:465
bool enable_http1
Serve/accept HTTP/1.1 (ALPN and/or cleartext).
Definition http2.h:171
absl::Time deadline
Connection-wide deadline.
Definition http2.h:164
std::function< bool(std::string_view method, std::string_view path, const HttpHeaders &headers)> stream_request_body
Server: decides from a request's head whether its body arrives incrementally.
Definition http2.h:207
size_t max_buffered_response_bytes
Response backpressure bound.
Definition http2.h:162
size_t max_request_body_size
Request hard limit.
Definition http2.h:158
bool enable_push
Client: accept HTTP/2 server pushes (SETTINGS_ENABLE_PUSH).
Definition http2.h:180
Definition http2.cc:2150
TLS settings for an HTTP/2 client or server (certificates, peer verification).
Definition http2.h:137
bool verify_peer
Validate the remote certificate and hostname.
Definition http2.h:139
std::string certificate_pem_file
Local certificate chain, if needed.
Definition http2.h:140
std::string ca_certificate_pem_file
Optional custom trust roots.
Definition http2.h:142
std::string key_pem_file
Private key matching the local certificate.
Definition http2.h:141
bool enabled
Negotiate TLS instead of clear-text HTTP/2.
Definition http2.h:138
absl::Status Validate() const
Validate certificate/key combinations before opening a socket.
Definition http2.cc:451
A response the server sent without being asked (HTTP/2 server push).
Definition http2.h:125
std::string method
Method of the promised request.
Definition http2.h:126
HttpHeaders headers
Header fields of the promised request.
Definition http2.h:130
std::shared_ptr< Http2ResponseStream > response
The pushed response: its own head, body, and trailers.
Definition http2.h:132
std::string scheme
Scheme of the promised request.
Definition http2.h:127
std::string authority
Authority of the promised request.
Definition http2.h:128
std::string path
Path and query of the promised request.
Definition http2.h:129
A parsed HTTP/2 request: pseudo-headers, fields, and body.
Definition http2.h:90
std::string body
Fully buffered body for an ordinary request.
Definition http2.h:97
std::shared_ptr< Http2RequestBodyStream > body_stream
Pull stream for a request still open after its headers, otherwise null.
Definition http2.h:99
std::string method
HTTP method pseudo-header.
Definition http2.h:91
std::string authority
Target authority/host.
Definition http2.h:94
std::string scheme
Request scheme pseudo-header.
Definition http2.h:93
std::string protocol
Extended CONNECT protocol, if present.
Definition http2.h:92
std::string path
Request path and query.
Definition http2.h:95
HttpHeaders headers
Normal application headers.
Definition http2.h:96
Status line and headers of an HTTP/2 response, without the body.
Definition http2.h:103
int status
Numeric HTTP response status.
Definition http2.h:104
HttpHeaders headers
Response headers, preserving repetitions.
Definition http2.h:105
A fully buffered HTTP/2 response: head plus complete body.
Definition http2.h:109
std::string body
Complete response body.
Definition http2.h:111
HttpResponseHead head
Status and headers.
Definition http2.h:110
std::string protocol
Definition main.cc:76
const std::shared_ptr< rtc::PeerConnection > connection
Definition webrtc_wire_stream.cc:110