xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/adapter/oghttp2_session.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #ifndef QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
2 #define QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
3 
4 #include <cstdint>
5 #include <limits>
6 #include <list>
7 #include <memory>
8 #include <optional>
9 #include <vector>
10 
11 #include "absl/strings/string_view.h"
12 #include "absl/types/variant.h"
13 #include "quiche/http2/adapter/data_source.h"
14 #include "quiche/http2/adapter/event_forwarder.h"
15 #include "quiche/http2/adapter/header_validator.h"
16 #include "quiche/http2/adapter/header_validator_base.h"
17 #include "quiche/http2/adapter/http2_protocol.h"
18 #include "quiche/http2/adapter/http2_session.h"
19 #include "quiche/http2/adapter/http2_util.h"
20 #include "quiche/http2/adapter/http2_visitor_interface.h"
21 #include "quiche/http2/adapter/window_manager.h"
22 #include "quiche/http2/core/http2_trace_logging.h"
23 #include "quiche/http2/core/priority_write_scheduler.h"
24 #include "quiche/common/platform/api/quiche_bug_tracker.h"
25 #include "quiche/common/platform/api/quiche_export.h"
26 #include "quiche/common/platform/api/quiche_flags.h"
27 #include "quiche/common/quiche_callbacks.h"
28 #include "quiche/common/quiche_circular_deque.h"
29 #include "quiche/common/quiche_linked_hash_map.h"
30 #include "quiche/spdy/core/http2_frame_decoder_adapter.h"
31 #include "quiche/spdy/core/http2_header_block.h"
32 #include "quiche/spdy/core/no_op_headers_handler.h"
33 #include "quiche/spdy/core/spdy_framer.h"
34 #include "quiche/spdy/core/spdy_protocol.h"
35 
36 namespace http2 {
37 namespace adapter {
38 
39 // This class manages state associated with a single multiplexed HTTP/2 session.
40 class QUICHE_EXPORT OgHttp2Session : public Http2Session,
41                                      public spdy::SpdyFramerVisitorInterface {
42  public:
43   struct QUICHE_EXPORT Options {
44     // Returns whether to send a WINDOW_UPDATE based on the window limit, window
45     // size, and delta that would be sent in the WINDOW_UPDATE.
46     WindowManager::ShouldWindowUpdateFn should_window_update_fn =
47         DeltaAtLeastHalfLimit;
48     // The perspective of this session.
49     Perspective perspective = Perspective::kClient;
50     // The maximum HPACK table size to use.
51     std::optional<size_t> max_hpack_encoding_table_capacity;
52     // The maximum number of decoded header bytes that a stream can receive.
53     std::optional<uint32_t> max_header_list_bytes = std::nullopt;
54     // The maximum size of an individual header field, including name and value.
55     std::optional<uint32_t> max_header_field_size = std::nullopt;
56     // The assumed initial value of the remote endpoint's max concurrent streams
57     // setting.
58     std::optional<uint32_t> remote_max_concurrent_streams = std::nullopt;
59     // Whether to automatically send PING acks when receiving a PING.
60     bool auto_ping_ack = true;
61     // Whether (as server) to send a RST_STREAM NO_ERROR when sending a fin on
62     // an incomplete stream.
63     bool rst_stream_no_error_when_incomplete = false;
64     // Whether to mark all input data as consumed upon encountering a connection
65     // error while processing bytes. If true, subsequent processing will also
66     // mark all input data as consumed.
67     bool blackhole_data_on_connection_error = true;
68     // Whether to advertise support for the extended CONNECT semantics described
69     // in RFC 8441. If true, this endpoint will send the appropriate setting in
70     // initial SETTINGS.
71     bool allow_extended_connect = true;
72     // Whether to allow `obs-text` (characters from hexadecimal 0x80 to 0xff) in
73     // header field values.
74     bool allow_obs_text = true;
75     // If true, validates header field names and values according to RFC 7230
76     // and RFC 7540.
77     bool validate_http_headers = true;
78     // If true, validate the `:path` pseudo-header according to RFC 3986
79     // Section 3.3.
80     bool validate_path = false;
81     // If true, allows the '#' character in request paths, even though this
82     // contradicts RFC 3986 Section 3.3.
83     // TODO(birenroy): Flip the default value to false.
84     bool allow_fragment_in_path = true;
85     // If true, allows different values for `host` and `:authority` headers to
86     // be present in request headers.
87     bool allow_different_host_and_authority = false;
88     // If true, crumbles `Cookie` header field values for potentially better
89     // HPACK compression.
90     bool crumble_cookies = false;
91   };
92 
93   OgHttp2Session(Http2VisitorInterface& visitor, Options options);
94   ~OgHttp2Session() override;
95 
96   // Enqueues a frame for transmission to the peer.
97   void EnqueueFrame(std::unique_ptr<spdy::SpdyFrameIR> frame);
98 
99   // Starts a graceful shutdown sequence. No-op if a GOAWAY has already been
100   // sent.
101   void StartGracefulShutdown();
102 
103   // Invokes the visitor's OnReadyToSend() method for serialized frames and
104   // DataFrameSource::Send() for data frames.
105   int Send();
106 
107   int32_t SubmitRequest(absl::Span<const Header> headers,
108                         std::unique_ptr<DataFrameSource> data_source,
109                         void* user_data);
110   int SubmitResponse(Http2StreamId stream_id, absl::Span<const Header> headers,
111                      std::unique_ptr<DataFrameSource> data_source);
112   int SubmitTrailer(Http2StreamId stream_id, absl::Span<const Header> trailers);
113   void SubmitMetadata(Http2StreamId stream_id,
114                       std::unique_ptr<MetadataSource> source);
115   void SubmitSettings(absl::Span<const Http2Setting> settings);
116 
IsServerSession()117   bool IsServerSession() const {
118     return options_.perspective == Perspective::kServer;
119   }
GetHighestReceivedStreamId()120   Http2StreamId GetHighestReceivedStreamId() const {
121     return highest_received_stream_id_;
122   }
123   void SetStreamUserData(Http2StreamId stream_id, void* user_data);
124   void* GetStreamUserData(Http2StreamId stream_id);
125 
126   // Resumes a stream that was previously blocked. Returns true on success.
127   bool ResumeStream(Http2StreamId stream_id);
128 
129   // Returns the peer's outstanding stream receive window for the given stream.
130   int GetStreamSendWindowSize(Http2StreamId stream_id) const;
131 
132   // Returns the current upper bound on the flow control receive window for this
133   // stream.
134   int GetStreamReceiveWindowLimit(Http2StreamId stream_id) const;
135 
136   // Returns the outstanding stream receive window, or -1 if the stream does not
137   // exist.
138   int GetStreamReceiveWindowSize(Http2StreamId stream_id) const;
139 
140   // Returns the outstanding connection receive window.
141   int GetReceiveWindowSize() const;
142 
143   // Returns the size of the HPACK encoder's dynamic table, including the
144   // per-entry overhead from the specification.
145   int GetHpackEncoderDynamicTableSize() const;
146 
147   // Returns the maximum capacity of the HPACK encoder's dynamic table.
148   int GetHpackEncoderDynamicTableCapacity() const;
149 
150   // Returns the size of the HPACK decoder's dynamic table, including the
151   // per-entry overhead from the specification.
152   int GetHpackDecoderDynamicTableSize() const;
153 
154   // Returns the size of the HPACK decoder's most recently applied size limit.
155   int GetHpackDecoderSizeLimit() const;
156 
GetMaxOutboundConcurrentStreams()157   uint32_t GetMaxOutboundConcurrentStreams() const {
158     return max_outbound_concurrent_streams_;
159   }
160 
161   // From Http2Session.
162   int64_t ProcessBytes(absl::string_view bytes) override;
163   int Consume(Http2StreamId stream_id, size_t num_bytes) override;
want_read()164   bool want_read() const override {
165     return !received_goaway_ && !decoder_.HasError();
166   }
want_write()167   bool want_write() const override {
168     return !fatal_send_error_ &&
169            (!frames_.empty() || !buffered_data_.empty() || HasReadyStream() ||
170             !goaway_rejected_streams_.empty());
171   }
GetRemoteWindowSize()172   int GetRemoteWindowSize() const override { return connection_send_window_; }
peer_enables_connect_protocol()173   bool peer_enables_connect_protocol() {
174     return peer_enables_connect_protocol_;
175   }
176 
177   // From SpdyFramerVisitorInterface
178   void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
179                std::string detailed_error) override;
180   void OnCommonHeader(spdy::SpdyStreamId /*stream_id*/, size_t /*length*/,
181                       uint8_t /*type*/, uint8_t /*flags*/) override;
182   void OnDataFrameHeader(spdy::SpdyStreamId stream_id, size_t length,
183                          bool fin) override;
184   void OnStreamFrameData(spdy::SpdyStreamId stream_id, const char* data,
185                          size_t len) override;
186   void OnStreamEnd(spdy::SpdyStreamId stream_id) override;
187   void OnStreamPadLength(spdy::SpdyStreamId /*stream_id*/,
188                          size_t /*value*/) override;
189   void OnStreamPadding(spdy::SpdyStreamId stream_id, size_t len) override;
190   spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart(
191       spdy::SpdyStreamId stream_id) override;
192   void OnHeaderFrameEnd(spdy::SpdyStreamId stream_id) override;
193   void OnRstStream(spdy::SpdyStreamId stream_id,
194                    spdy::SpdyErrorCode error_code) override;
195   void OnSettings() override;
196   void OnSetting(spdy::SpdySettingsId id, uint32_t value) override;
197   void OnSettingsEnd() override;
198   void OnSettingsAck() override;
199   void OnPing(spdy::SpdyPingId unique_id, bool is_ack) override;
200   void OnGoAway(spdy::SpdyStreamId last_accepted_stream_id,
201                 spdy::SpdyErrorCode error_code) override;
202   bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
203   void OnHeaders(spdy::SpdyStreamId stream_id, size_t payload_length,
204                  bool has_priority, int weight,
205                  spdy::SpdyStreamId parent_stream_id, bool exclusive, bool fin,
206                  bool end) override;
207   void OnWindowUpdate(spdy::SpdyStreamId stream_id,
208                       int delta_window_size) override;
209   void OnPushPromise(spdy::SpdyStreamId stream_id,
210                      spdy::SpdyStreamId promised_stream_id, bool end) override;
211   void OnContinuation(spdy::SpdyStreamId stream_id, size_t payload_length,
212                       bool end) override;
213   void OnAltSvc(spdy::SpdyStreamId /*stream_id*/, absl::string_view /*origin*/,
214                 const spdy::SpdyAltSvcWireFormat::
215                     AlternativeServiceVector& /*altsvc_vector*/) override;
216   void OnPriority(spdy::SpdyStreamId stream_id,
217                   spdy::SpdyStreamId parent_stream_id, int weight,
218                   bool exclusive) override;
219   void OnPriorityUpdate(spdy::SpdyStreamId prioritized_stream_id,
220                         absl::string_view priority_field_value) override;
221   bool OnUnknownFrame(spdy::SpdyStreamId stream_id,
222                       uint8_t frame_type) override;
223   void OnUnknownFrameStart(spdy::SpdyStreamId stream_id, size_t length,
224                            uint8_t type, uint8_t flags) override;
225   void OnUnknownFramePayload(spdy::SpdyStreamId stream_id,
226                              absl::string_view payload) override;
227 
228   // Invoked when header processing encounters an invalid or otherwise
229   // problematic header.
230   void OnHeaderStatus(Http2StreamId stream_id,
231                       Http2VisitorInterface::OnHeaderResult result);
232 
233  private:
234   struct QUICHE_EXPORT StreamState {
StreamStateStreamState235     StreamState(int32_t stream_receive_window, int32_t stream_send_window,
236                 WindowManager::WindowUpdateListener listener,
237                 WindowManager::ShouldWindowUpdateFn should_window_update_fn)
238         : window_manager(stream_receive_window, std::move(listener),
239                          std::move(should_window_update_fn),
240                          /*update_window_on_notify=*/false),
241           send_window(stream_send_window) {}
242 
243     WindowManager window_manager;
244     std::unique_ptr<DataFrameSource> outbound_body;
245     std::unique_ptr<spdy::Http2HeaderBlock> trailers;
246     void* user_data = nullptr;
247     int32_t send_window;
248     std::optional<HeaderType> received_header_type;
249     std::optional<size_t> remaining_content_length;
250     bool half_closed_local = false;
251     bool half_closed_remote = false;
252     // Indicates that `outbound_body` temporarily cannot produce data.
253     bool data_deferred = false;
254     bool sent_head_method = false;
255     bool can_receive_body = true;
256   };
257   using StreamStateMap = absl::flat_hash_map<Http2StreamId, StreamState>;
258 
259   struct QUICHE_EXPORT PendingStreamState {
260     spdy::Http2HeaderBlock headers;
261     std::unique_ptr<DataFrameSource> data_source;
262     void* user_data = nullptr;
263   };
264 
265   class QUICHE_EXPORT PassthroughHeadersHandler
266       : public spdy::SpdyHeadersHandlerInterface {
267    public:
268     PassthroughHeadersHandler(OgHttp2Session& session,
269                               Http2VisitorInterface& visitor);
270 
Reset()271     void Reset() {
272       error_encountered_ = false;
273     }
274 
set_stream_id(Http2StreamId stream_id)275     void set_stream_id(Http2StreamId stream_id) { stream_id_ = stream_id; }
set_frame_contains_fin(bool value)276     void set_frame_contains_fin(bool value) { frame_contains_fin_ = value; }
set_header_type(HeaderType type)277     void set_header_type(HeaderType type) { type_ = type; }
header_type()278     HeaderType header_type() const { return type_; }
279 
280     void OnHeaderBlockStart() override;
281     void OnHeader(absl::string_view key, absl::string_view value) override;
282     void OnHeaderBlockEnd(size_t /* uncompressed_header_bytes */,
283                           size_t /* compressed_header_bytes */) override;
status_header()284     absl::string_view status_header() const {
285       QUICHE_DCHECK(type_ == HeaderType::RESPONSE ||
286                     type_ == HeaderType::RESPONSE_100);
287       return validator_->status_header();
288     }
content_length()289     std::optional<size_t> content_length() const {
290       return validator_->content_length();
291     }
SetAllowExtendedConnect()292     void SetAllowExtendedConnect() { validator_->SetAllowExtendedConnect(); }
SetMaxFieldSize(uint32_t field_size)293     void SetMaxFieldSize(uint32_t field_size) {
294       validator_->SetMaxFieldSize(field_size);
295     }
SetAllowObsText(bool allow)296     void SetAllowObsText(bool allow) {
297       validator_->SetObsTextOption(allow ? ObsTextOption::kAllow
298                                          : ObsTextOption::kDisallow);
299     }
300     bool CanReceiveBody() const;
301 
302    private:
303     void SetResult(Http2VisitorInterface::OnHeaderResult result);
304 
305     OgHttp2Session& session_;
306     Http2VisitorInterface& visitor_;
307     Http2StreamId stream_id_ = 0;
308     // Validates header blocks according to the HTTP/2 specification.
309     std::unique_ptr<HeaderValidatorBase> validator_;
310     HeaderType type_ = HeaderType::RESPONSE;
311     bool frame_contains_fin_ = false;
312     bool error_encountered_ = false;
313   };
314 
315   struct QUICHE_EXPORT ProcessBytesResultVisitor;
316 
317   // Queues the connection preface, if not already done. If not
318   // `sending_outbound_settings` and the preface has not yet been queued, this
319   // method will generate and enqueue initial SETTINGS.
320   void MaybeSetupPreface(bool sending_outbound_settings);
321 
322   // Gets the settings to be sent in the initial SETTINGS frame sent as part of
323   // the connection preface.
324   std::vector<Http2Setting> GetInitialSettings() const;
325 
326   // Prepares and returns a SETTINGS frame with the given `settings`.
327   std::unique_ptr<spdy::SpdySettingsIR> PrepareSettingsFrame(
328       absl::Span<const Http2Setting> settings);
329 
330   // Updates internal state to match the SETTINGS advertised to the peer.
331   void HandleOutboundSettings(const spdy::SpdySettingsIR& settings_frame);
332 
333   void SendWindowUpdate(Http2StreamId stream_id, size_t update_delta);
334 
335   enum class SendResult {
336     // All data was flushed.
337     SEND_OK,
338     // Not all data was flushed (due to flow control or TCP back pressure).
339     SEND_BLOCKED,
340     // An error occurred while sending data.
341     SEND_ERROR,
342   };
343 
344   // Returns the int corresponding to the `result`, updating state as needed.
345   int InterpretSendResult(SendResult result);
346 
347   enum class ProcessBytesError {
348     // A general, unspecified error.
349     kUnspecified,
350     // The (server-side) session received an invalid client connection preface.
351     kInvalidConnectionPreface,
352     // A user/visitor callback failed with a fatal error.
353     kVisitorCallbackFailed,
354   };
355   using ProcessBytesResult = absl::variant<int64_t, ProcessBytesError>;
356 
357   // Attempts to process `bytes` and returns the number of bytes proccessed on
358   // success or the processing error on failure.
359   ProcessBytesResult ProcessBytesImpl(absl::string_view bytes);
360 
361   // Returns true if at least one stream has data or control frames to write.
362   bool HasReadyStream() const;
363 
364   // Returns the next stream that has something to write. If there are no such
365   // streams, returns zero.
366   Http2StreamId GetNextReadyStream();
367 
368   int32_t SubmitRequestInternal(absl::Span<const Header> headers,
369                                 std::unique_ptr<DataFrameSource> data_source,
370                                 void* user_data);
371   int SubmitResponseInternal(Http2StreamId stream_id,
372                              absl::Span<const Header> headers,
373                              std::unique_ptr<DataFrameSource> data_source);
374 
375   // Sends the buffered connection preface or serialized frame data, if any.
376   SendResult MaybeSendBufferedData();
377 
378   // Serializes and sends queued frames.
379   SendResult SendQueuedFrames();
380 
381   // Returns false if a fatal connection error occurred.
382   bool AfterFrameSent(uint8_t frame_type_int, uint32_t stream_id,
383                       size_t payload_length, uint8_t flags,
384                       uint32_t error_code);
385 
386   // Writes DATA frames for stream `stream_id`.
387   SendResult WriteForStream(Http2StreamId stream_id);
388 
389   void SerializeMetadata(Http2StreamId stream_id,
390                          std::unique_ptr<MetadataSource> source);
391 
392   void SendHeaders(Http2StreamId stream_id, spdy::Http2HeaderBlock headers,
393                    bool end_stream);
394 
395   void SendTrailers(Http2StreamId stream_id, spdy::Http2HeaderBlock trailers);
396 
397   // Encapsulates the RST_STREAM NO_ERROR behavior described in RFC 7540
398   // Section 8.1.
399   void MaybeFinWithRstStream(StreamStateMap::iterator iter);
400 
401   // Performs flow control accounting for data sent by the peer.
402   void MarkDataBuffered(Http2StreamId stream_id, size_t bytes);
403 
404   // Creates a stream for `stream_id` if not already present and returns an
405   // iterator pointing to it.
406   StreamStateMap::iterator CreateStream(Http2StreamId stream_id);
407 
408   // Creates a stream for `stream_id`, stores the `data_source` and `user_data`
409   // in the stream state, and sends the `headers`.
410   void StartRequest(Http2StreamId stream_id, spdy::Http2HeaderBlock headers,
411                     std::unique_ptr<DataFrameSource> data_source,
412                     void* user_data);
413 
414   // Sends headers for pending streams as long as the stream limit allows.
415   void StartPendingStreams();
416 
417   // Closes the given `stream_id` with the given `error_code`.
418   void CloseStream(Http2StreamId stream_id, Http2ErrorCode error_code);
419 
420   // Calculates the next expected header type for a stream in a given state.
421   HeaderType NextHeaderType(std::optional<HeaderType> current_type);
422 
423   // Returns true if the session can create a new stream.
424   bool CanCreateStream() const;
425 
426   // Informs the visitor of the connection `error` and stops processing on the
427   // connection. If server-side, also sends a GOAWAY with `error_code`.
428   void LatchErrorAndNotify(Http2ErrorCode error_code,
429                            Http2VisitorInterface::ConnectionError error);
430 
431   void CloseStreamIfReady(uint8_t frame_type, uint32_t stream_id);
432 
433   // Informs the visitor of rejected, non-active streams due to GOAWAY receipt.
434   void CloseGoAwayRejectedStreams();
435 
436   // Updates internal state to prepare for sending an immediate GOAWAY.
437   void PrepareForImmediateGoAway();
438 
439   // Handles the potential end of received metadata for the given `stream_id`.
440   void MaybeHandleMetadataEndForStream(Http2StreamId stream_id);
441 
442   void DecrementQueuedFrameCount(uint32_t stream_id, uint8_t frame_type);
443 
444   void HandleContentLengthError(Http2StreamId stream_id);
445 
446   // Invoked when sending a flow control window update to the peer.
447   void UpdateReceiveWindow(Http2StreamId stream_id, int32_t delta);
448 
449   // Updates stream send window accounting to respect the peer's advertised
450   // initial window setting.
451   void UpdateStreamSendWindowSizes(uint32_t new_value);
452 
453   // Updates stream receive window managers to use the newly advertised stream
454   // initial window.
455   void UpdateStreamReceiveWindowSizes(uint32_t new_value);
456 
457   // Returns true if the given stream has additional data to write before
458   // trailers or the end of the stream.
459   bool HasMoreData(const StreamState& stream_state) const;
460 
461   // Returns true if the given stream has data ready to write. Trailers are
462   // considered separately.
463   bool IsReadyToWriteData(const StreamState& stream_state) const;
464 
465   // Abandons any remaining data, e.g. on stream reset.
466   void AbandonData(StreamState& stream_state);
467 
468   // Gathers information required to construct a DATA frame header.
469   struct DataFrameInfo {
470     int64_t payload_length;
471     bool end_data;
472     bool send_fin;
473   };
474   DataFrameInfo GetDataFrameInfo(Http2StreamId stream_id,
475                                  size_t flow_control_available,
476                                  StreamState& stream_state);
477 
478   // Invokes the appropriate API to send a DATA frame header and payload.
479   bool SendDataFrame(Http2StreamId stream_id, absl::string_view frame_header,
480                      size_t payload_length, StreamState& stream_state);
481 
482   // Receives events when inbound frames are parsed.
483   Http2VisitorInterface& visitor_;
484 
485   const Options options_;
486 
487   // Forwards received events to the session if it can accept them.
488   EventForwarder event_forwarder_;
489 
490   // Logs received frames when enabled.
491   Http2TraceLogger receive_logger_;
492   // Logs sent frames when enabled.
493   Http2FrameLogger send_logger_;
494 
495   // Encodes outbound frames.
496   spdy::SpdyFramer framer_{spdy::SpdyFramer::ENABLE_COMPRESSION};
497 
498   // Decodes inbound frames.
499   http2::Http2DecoderAdapter decoder_;
500 
501   // Maintains the state of active streams known to this session.
502   StreamStateMap stream_map_;
503 
504   // Maintains the state of pending streams known to this session. A pending
505   // stream is kept in this list until it can be created while complying with
506   // `max_outbound_concurrent_streams_`.
507   quiche::QuicheLinkedHashMap<Http2StreamId, PendingStreamState>
508       pending_streams_;
509 
510   // The queue of outbound frames.
511   std::list<std::unique_ptr<spdy::SpdyFrameIR>> frames_;
512   // Buffered data (connection preface, serialized frames) that has not yet been
513   // sent.
514   std::string buffered_data_;
515 
516   // Maintains the set of streams ready to write data to the peer.
517   using WriteScheduler = PriorityWriteScheduler<Http2StreamId>;
518   WriteScheduler write_scheduler_;
519 
520   // Stores the queue of callbacks to invoke upon receiving SETTINGS acks. At
521   // most one callback is invoked for each SETTINGS ack.
522   using SettingsAckCallback = quiche::SingleUseCallback<void()>;
523   quiche::QuicheCircularDeque<SettingsAckCallback> settings_ack_callbacks_;
524 
525   // Delivers header name-value pairs to the visitor.
526   PassthroughHeadersHandler headers_handler_;
527 
528   // Ignores header data, e.g., for an unknown or rejected stream.
529   spdy::NoOpHeadersHandler noop_headers_handler_;
530 
531   // Tracks the remaining client connection preface, in the case of a server
532   // session.
533   absl::string_view remaining_preface_;
534 
535   WindowManager connection_window_manager_;
536 
537   // Tracks the streams that have been marked for reset. A stream is removed
538   // from this set once it is closed.
539   absl::flat_hash_set<Http2StreamId> streams_reset_;
540 
541   // The number of frames currently queued per stream.
542   absl::flat_hash_map<Http2StreamId, int> queued_frames_;
543   // Includes streams that are currently ready to write trailers.
544   absl::flat_hash_set<Http2StreamId> trailers_ready_;
545   // Includes streams that will not be written due to receipt of GOAWAY.
546   absl::flat_hash_set<Http2StreamId> goaway_rejected_streams_;
547 
548   Http2StreamId next_stream_id_ = 1;
549   // The highest received stream ID is the highest stream ID in any frame read
550   // from the peer. The highest processed stream ID is the highest stream ID for
551   // which this endpoint created a stream in the stream map.
552   Http2StreamId highest_received_stream_id_ = 0;
553   Http2StreamId highest_processed_stream_id_ = 0;
554   Http2StreamId received_goaway_stream_id_ = 0;
555   size_t metadata_length_ = 0;
556   int32_t connection_send_window_ = kInitialFlowControlWindowSize;
557   // The initial flow control receive window size for any newly created streams.
558   int32_t initial_stream_receive_window_ = kInitialFlowControlWindowSize;
559   // The initial flow control send window size for any newly created streams.
560   int32_t initial_stream_send_window_ = kInitialFlowControlWindowSize;
561   uint32_t max_frame_payload_ = kDefaultFramePayloadSizeLimit;
562   // The maximum number of concurrent streams that this connection can open to
563   // its peer. Although the initial value
564   // is unlimited, the spec encourages a value of at least 100. Initially 100 or
565   // the specified option until told otherwise by the peer.
566   uint32_t max_outbound_concurrent_streams_;
567   // The maximum number of concurrent streams that this connection allows from
568   // its peer. Unlimited, until SETTINGS with some other value is acknowledged.
569   uint32_t pending_max_inbound_concurrent_streams_ =
570       std::numeric_limits<uint32_t>::max();
571   uint32_t max_inbound_concurrent_streams_ =
572       std::numeric_limits<uint32_t>::max();
573 
574   // The HPACK encoder header table capacity that will be applied when
575   // acking SETTINGS from the peer. Only contains a value if the peer advertises
576   // a larger table capacity than currently used; a smaller value can safely be
577   // applied immediately upon receipt.
578   std::optional<uint32_t> encoder_header_table_capacity_when_acking_;
579 
580   uint8_t current_frame_type_ = 0;
581 
582   bool received_goaway_ = false;
583   bool queued_preface_ = false;
584   bool peer_supports_metadata_ = false;
585   bool end_metadata_ = false;
586   bool process_metadata_ = false;
587   bool sent_non_ack_settings_ = false;
588 
589   // Recursion guard for ProcessBytes().
590   bool processing_bytes_ = false;
591   // Recursion guard for Send().
592   bool sending_ = false;
593 
594   bool peer_enables_connect_protocol_ = false;
595 
596   // Replace this with a stream ID, for multiple GOAWAY support.
597   bool queued_goaway_ = false;
598   bool queued_immediate_goaway_ = false;
599   bool latched_error_ = false;
600 
601   // True if a fatal sending error has occurred.
602   bool fatal_send_error_ = false;
603 
604   // True if a fatal processing visitor callback failed.
605   bool fatal_visitor_callback_failure_ = false;
606 };
607 
608 }  // namespace adapter
609 }  // namespace http2
610 
611 #endif  // QUICHE_HTTP2_ADAPTER_OGHTTP2_SESSION_H_
612