A11 (C++ runtime)
Native C++ implementation of the A11 action and streaming runtime
Loading...
Searching...
No Matches
http_sse_wire_stream.h
Go to the documentation of this file.
1// Copyright 2026 The A11 Authors.
2
18#ifndef A11_NET_HTTP_SSE_WIRE_STREAM_H_
19#define A11_NET_HTTP_SSE_WIRE_STREAM_H_
20
21#include <cstdint>
22#include <functional>
23#include <memory>
24#include <optional>
25#include <string>
26
27#include <absl/base/nullability.h>
28#include <absl/status/status.h>
29#include <absl/status/statusor.h>
30#include <absl/time/time.h>
31
33#include "a11/data/types.h"
34#include "a11/net/http2.h"
36#include "a11/net/wire_stream.h"
37
38namespace a11::net {
39
41inline constexpr std::string_view kSseStreamIdHeader = "x-a11-stream-id";
43inline constexpr std::string_view kSseHttpHeaderPrefix = "x-a11-http-";
45inline constexpr std::string_view kDefaultSseConnectEndpoint = "/connect";
47inline constexpr std::string_view kDefaultSseMessageEndpoint =
48 "/streams/{id}/message";
49
73
83 : public WireStream,
84 public std::enable_shared_from_this<HttpSseWireStream> {
85 public:
86 ~HttpSseWireStream() override = default;
87
90
91 absl::Status Send(data::WireMessage message) override;
92 a11::Task Start(OnMessage on_message, OnDone on_done) override;
93 a11::Task Accept(OnMessage on_message, OnDone on_done) override;
94 absl::Status HalfClose(data::ByteMap trailers) override;
96 absl::Status Abort(absl::Status status) override;
97 absl::Status SetDeadline(absl::Time deadline) override;
98
99 [[nodiscard]] absl::Time deadline() const override;
100 [[nodiscard]] absl::Status GetStatus() const override;
101 [[nodiscard]] std::optional<data::ByteMap> GetTrailers() const override;
102 [[nodiscard]] std::string GetId() const override;
103 [[nodiscard]] void* absl_nullable GetImpl() const override;
104
109 [[nodiscard]] std::optional<HttpHeaders> GetHttpResponseHeaders() const;
111 absl::Status SetHttpRequestHeaders(HttpHeaders headers);
113 absl::Status SetHttpResponseHeaders(HttpHeaders headers);
117
118 protected:
119 enum class Role { kClient, kServer };
120 struct State;
121
122 HttpSseWireStream(Role role, std::string id, HttpSseOptions options,
124 std::shared_ptr<State> state);
125
126 a11::Task StartEndpoint(bool accept, OnMessage on_message, OnDone on_done);
128 a11::Task HandleBridgeMessage(std::optional<data::WireMessage> message);
131 void FailTransport(absl::Status status);
132 void MarkHttpHeadersReady(HttpHeaders headers);
133 void SetId(std::string id);
134 [[nodiscard]] HttpSseOptions options() const;
135 [[nodiscard]] std::shared_ptr<InProcessWireStream> bridge() const;
136
138 virtual absl::Status Transmit(data::WireMessage message) = 0;
139 virtual void* absl_nullable TransportImpl() const = 0;
140
141 virtual void TransportDone() {}
142
143 private:
144 Role role_;
145 std::shared_ptr<InProcessWireStream> application_;
146 std::shared_ptr<InProcessWireStream> bridge_;
147 std::shared_ptr<State> state_;
148
149 friend class HttpSseServer;
150};
151
159 private:
160 struct ClientState;
161
162 struct ConstructorToken {};
163
164 public:
175 static absl::StatusOr<std::shared_ptr<HttpSseClientWireStream>> Create(
176 std::string url, HttpSseOptions options = {},
177 std::shared_ptr<Http2Client> client = nullptr,
179
182 [[nodiscard]] std::shared_ptr<Http2Client> client() const;
183
184 HttpSseClientWireStream(ConstructorToken, std::string url,
187 std::shared_ptr<State> state,
188 std::shared_ptr<ClientState> client_state);
189
190 protected:
191 a11::Task OpenTransport() override;
192 absl::Status Transmit(data::WireMessage message) override;
193 void* absl_nullable TransportImpl() const override;
194
195 private:
196 static void ReceiveSseLoop(
197 const std::shared_ptr<HttpSseClientWireStream>& self);
198
199 std::shared_ptr<ClientState> client_state_;
200};
201
202class HttpSseServer;
203
211 private:
212 struct ServerStreamState;
213
214 struct ConstructorToken {};
215
216 public:
219 a11::Task Accepted() const;
220
221 HttpSseServerWireStream(ConstructorToken, std::string id,
224 std::shared_ptr<State> state,
225 std::shared_ptr<ServerStreamState> server_state);
226
227 protected:
228 a11::Task OpenTransport() override;
229 absl::Status Transmit(data::WireMessage message) override;
230 void* absl_nullable TransportImpl() const override;
231 void TransportDone() override;
232
233 private:
234 std::shared_ptr<ServerStreamState> server_state_;
235
236 friend class HttpSseServer;
237};
238
241 std::function<a11::Task(std::shared_ptr<HttpSseServerWireStream>)>;
242
249class HttpSseServer : public std::enable_shared_from_this<HttpSseServer> {
250 public:
260 static absl::StatusOr<std::shared_ptr<HttpSseServer>> Create(
261 std::string bind_address, std::uint16_t port,
262 OnHttpSseConnect on_connect = {}, HttpSseOptions options = {});
263
265
269 absl::Status Stop();
271 [[nodiscard]] std::uint16_t port() const;
273 [[nodiscard]] bool running() const;
275 [[nodiscard]] std::shared_ptr<Http2Server> http2_server() const;
276
277 private:
278 struct State;
279
280 explicit HttpSseServer(std::shared_ptr<State> state)
281 : state_(std::move(state)) {}
282
283 static a11::Task HandleRequest(const std::shared_ptr<State>& state,
284 HttpRequest request,
285 std::shared_ptr<Http2ResponseWriter> response);
286 static a11::Task HandleConnect(const std::shared_ptr<State>& state,
287 HttpRequest request,
288 std::shared_ptr<Http2ResponseWriter> response);
289 static a11::Task HandleMessage(const std::shared_ptr<State>& state,
290 std::string stream_id, HttpRequest request,
291 std::shared_ptr<Http2ResponseWriter> response);
292
293 std::shared_ptr<State> state_;
294
296};
297
300
301} // namespace a11::net
302
303#endif // A11_NET_HTTP_SSE_WIRE_STREAM_H_
The client-side HTTP SSE wire stream, dialing out to a server URL.
Definition http_sse_wire_stream.h:158
std::shared_ptr< Http2Client > client() const
Definition http_sse_wire_stream.cc:615
void *absl_nullable TransportImpl() const override
Definition http_sse_wire_stream.cc:831
a11::Task OpenTransport() override
Definition http_sse_wire_stream.cc:620
static absl::StatusOr< std::shared_ptr< HttpSseClientWireStream > > Create(std::string url, HttpSseOptions options={}, std::shared_ptr< Http2Client > client=nullptr, HttpHeaders request_headers={})
Creates a client SSE wire stream connecting to url.
Definition http_sse_wire_stream.cc:560
absl::Status Transmit(data::WireMessage message) override
Definition http_sse_wire_stream.cc:697
The server-side HTTP SSE wire stream, accepted from a client.
Definition http_sse_wire_stream.h:210
a11::Task Accepted() const
Definition http_sse_wire_stream.cc:859
void *absl_nullable TransportImpl() const override
Definition http_sse_wire_stream.cc:914
void TransportDone() override
Definition http_sse_wire_stream.cc:918
absl::Status Transmit(data::WireMessage message) override
Definition http_sse_wire_stream.cc:895
a11::Task OpenTransport() override
Definition http_sse_wire_stream.cc:863
Hosts HTTP SSE wire streams on top of an HTTP/2 server.
Definition http_sse_wire_stream.h:249
std::uint16_t port() const
Definition http_sse_wire_stream.cc:1297
absl::Status Stop()
Stops the server and releases its resources.
Definition http_sse_wire_stream.cc:1269
~HttpSseServer()
Definition http_sse_wire_stream.cc:1044
std::shared_ptr< Http2Server > http2_server() const
Definition http_sse_wire_stream.cc:1308
bool running() const
Definition http_sse_wire_stream.cc:1302
static absl::StatusOr< std::shared_ptr< HttpSseServer > > Create(std::string bind_address, std::uint16_t port, OnHttpSseConnect on_connect={}, HttpSseOptions options={})
Creates and starts an SSE server accepting A11 wire streams.
Definition http_sse_wire_stream.cc:1008
a11::Future< std::shared_ptr< HttpSseServerWireStream > > WaitForStream()
Definition http_sse_wire_stream.cc:1249
Common base for the client and server HTTP SSE wire streams.
Definition http_sse_wire_stream.h:84
Role
Definition http_sse_wire_stream.h:119
absl::Status Abort(absl::Status status) override
Abort the stream, discarding buffered work.
Definition http_sse_wire_stream.cc:411
a11::Task Start(OnMessage on_message, OnDone on_done) override
Begin the stream as the initiating ("start") side.
Definition http_sse_wire_stream.cc:235
void FailTransport(absl::Status status)
Definition http_sse_wire_stream.cc:387
a11::Task ReceiveTransportMessage(data::WireMessage message)
Definition http_sse_wire_stream.cc:366
absl::Status SetHttpRequestHeaders(HttpHeaders headers)
Sets HTTP headers to send on the SSE request; call before connecting.
Definition http_sse_wire_stream.cc:465
virtual absl::Status Transmit(data::WireMessage message)=0
a11::Task Accept(OnMessage on_message, OnDone on_done) override
Begin the stream as the accepting ("accept") side.
Definition http_sse_wire_stream.cc:239
absl::Status SetDeadline()
Clear any deadline (equivalent to an infinite deadline).
Definition wire_stream.h:154
absl::Status GetStatus() const override
Definition http_sse_wire_stream.cc:431
absl::Status Send(data::WireMessage message) override
Enqueue a message for delivery to the peer.
Definition http_sse_wire_stream.cc:231
absl::Status HalfClose()
Half-close with no trailers.
Definition wire_stream.h:125
void *absl_nullable GetImpl() const override
Definition http_sse_wire_stream.cc:451
void MarkHttpHeadersReady(HttpHeaders headers)
Definition http_sse_wire_stream.cc:505
a11::Task StartEndpoint(bool accept, OnMessage on_message, OnDone on_done)
Definition http_sse_wire_stream.cc:243
HttpHeaders GetHttpRequestHeaders() const
Definition http_sse_wire_stream.cc:455
virtual void TransportDone()
Definition http_sse_wire_stream.h:141
std::string GetId() const override
Definition http_sse_wire_stream.cc:446
std::optional< HttpHeaders > GetHttpResponseHeaders() const
Definition http_sse_wire_stream.cc:460
a11::Task StartInternalBridge()
Definition http_sse_wire_stream.cc:289
absl::Status SetHttpResponseHeaders(HttpHeaders headers)
Sets HTTP headers to send on the SSE response (server side).
Definition http_sse_wire_stream.cc:483
a11::Task WaitForHttpHeaders() const
Definition http_sse_wire_stream.cc:501
absl::Time deadline() const override
Definition http_sse_wire_stream.cc:427
virtual void *absl_nullable TransportImpl() const =0
std::shared_ptr< InProcessWireStream > bridge() const
Definition http_sse_wire_stream.cc:530
void SetId(std::string id)
Definition http_sse_wire_stream.cc:520
virtual a11::Task OpenTransport()=0
std::optional< data::ByteMap > GetTrailers() const override
Definition http_sse_wire_stream.cc:442
a11::Task HandleBridgeMessage(std::optional< data::WireMessage > message)
Definition http_sse_wire_stream.cc:311
HttpSseOptions options() const
Definition http_sse_wire_stream.cc:525
a11::Task HandleBridgeDone()
Definition http_sse_wire_stream.cc:331
a11::Task DrainOutgoingMessages() override
Await delivery of all buffered outbound messages.
Definition http_sse_wire_stream.cc:407
~HttpSseWireStream() override=default
std::pair< std::shared_ptr< InProcessWireStream >, std::shared_ptr< InProcessWireStream > > Pair
A connected pair of endpoints returned by CreatePair().
Definition in_process_wire_stream.h:53
A bidirectional, message-oriented channel between two A11 endpoints.
Definition wire_stream.h:89
absl::Status SetDeadline()
Clear any deadline (equivalent to an infinite deadline).
Definition wire_stream.h:154
absl::Status HalfClose()
Half-close with no trailers.
Definition wire_stream.h:125
Completion values used by every asynchronous A11 operation.
A11's nghttp2 HTTP/2 client, server, and streaming primitives.
In-memory paired WireStream that connects two endpoints without a network.
absl::flat_hash_map< std::string, Bytes > ByteMap
String-keyed map of byte values (headers, attributes, etc.).
Definition types.h:42
Definition action.h:46
std::function< a11::Task(std::optional< data::WireMessage > message)> OnMessage
Called for each inbound message; std::nullopt signals the peer half-closed.
Definition wire_stream.h:65
std::function< a11::Task()> OnDone
Called once, when the stream has fully finished (cleanly or via abort).
Definition wire_stream.h:67
std::vector< std::pair< std::string, std::string > > HttpHeaders
An ordered list of (name, value) HTTP/2 header fields.
Definition http2.h:45
constexpr std::string_view kSseStreamIdHeader
Response header naming the stream id assigned to an SSE connection.
Definition http_sse_wire_stream.h:41
constexpr std::string_view kDefaultSseConnectEndpoint
Default path on which a client opens the SSE event stream.
Definition http_sse_wire_stream.h:45
constexpr std::string_view kSseHttpHeaderPrefix
Prefix under which application HTTP headers are tunneled over SSE.
Definition http_sse_wire_stream.h:43
constexpr std::string_view kDefaultSseMessageEndpoint
Default message-post path template ({id} is the stream id).
Definition http_sse_wire_stream.h:47
std::function< a11::Task(std::shared_ptr< HttpSseServerWireStream >)> OnHttpSseConnect
Callback invoked with each accepted server-side SSE wire stream.
Definition http_sse_wire_stream.h:241
Future< Unit > Task
Asynchronous operation whose only successful result is completion itself.
Definition future.h:403
Future< T > SubmitWithCancellationHook(absl::AnyInvocable< absl::StatusOr< T >() && > work, std::function< void()> cancellation_hook, thread::TreeOptions tree_options)
Run work on A11's fiber pool with application-specific cancellation.
Definition executor.h:30
The top-level frame exchanged between two A11 endpoints.
Definition types.h:275
Body-size limits, buffering thresholds, deadline, and TLS for an HTTP/2 client or server.
Definition http2.h:103
A parsed HTTP/2 request: pseudo-headers, fields, and body.
Definition http2.h:64
Definition http_sse_wire_stream.cc:534
Endpoint paths and transport tuning for an HTTP SSE wire stream.
Definition http_sse_wire_stream.h:58
std::string cors_allow_headers
Access-Control-Allow-Headers value.
Definition http_sse_wire_stream.h:67
std::string cors_allow_origin
Access-Control-Allow-Origin value.
Definition http_sse_wire_stream.h:65
WireStreamOptions stream_options
Per-stream buffering and deadline.
Definition http_sse_wire_stream.h:59
std::string message_endpoint
Outbound POST template.
Definition http_sse_wire_stream.h:63
std::string cors_allow_methods
Access-Control-Allow-Methods value.
Definition http_sse_wire_stream.h:66
absl::Status Validate() const
Definition http_sse_wire_stream.cc:193
std::string cors_expose_headers
Access-Control-Expose-Headers value.
Definition http_sse_wire_stream.h:68
std::string connect_endpoint
SSE connect POST path.
Definition http_sse_wire_stream.h:61
Http2Options http2_options
Shared HTTP/2 transport and TLS policy.
Definition http_sse_wire_stream.h:60
Definition http_sse_wire_stream.cc:838
Definition http_sse_wire_stream.cc:928
Buffering, sizing, and deadline limits for a WireStream endpoint.
Definition wire_stream.h:44
A11's core wire value types: chunks, node fragments and messages.
A11's transport abstraction: the bidirectional WireStream channel and the options/callbacks that driv...