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