1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_ 6 #define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_ 7 8 #include <cstddef> 9 #include <memory> 10 #include <string> 11 12 #include "absl/strings/string_view.h" 13 #include "absl/types/optional.h" 14 #include "net/third_party/quiche/src/quic/core/http/http_frames.h" 15 #include "net/third_party/quiche/src/quic/core/http/quic_header_list.h" 16 #include "net/third_party/quiche/src/quic/core/http/quic_headers_stream.h" 17 #include "net/third_party/quiche/src/quic/core/http/quic_receive_control_stream.h" 18 #include "net/third_party/quiche/src/quic/core/http/quic_send_control_stream.h" 19 #include "net/third_party/quiche/src/quic/core/http/quic_spdy_stream.h" 20 #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder.h" 21 #include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_stream_sender.h" 22 #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h" 23 #include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder_stream_sender.h" 24 #include "net/third_party/quiche/src/quic/core/qpack/qpack_receive_stream.h" 25 #include "net/third_party/quiche/src/quic/core/qpack/qpack_send_stream.h" 26 #include "net/third_party/quiche/src/quic/core/quic_session.h" 27 #include "net/third_party/quiche/src/quic/core/quic_time.h" 28 #include "net/third_party/quiche/src/quic/core/quic_types.h" 29 #include "net/third_party/quiche/src/quic/core/quic_versions.h" 30 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" 31 #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h" 32 33 namespace quic { 34 35 namespace test { 36 class QuicSpdySessionPeer; 37 } // namespace test 38 39 // QuicHpackDebugVisitor gathers data used for understanding HPACK HoL 40 // dynamics. Specifically, it is to help predict the compression 41 // penalty of avoiding HoL by chagning how the dynamic table is used. 42 // In chromium, the concrete instance populates an UMA 43 // histogram with the data. 44 class QUIC_EXPORT_PRIVATE QuicHpackDebugVisitor { 45 public: 46 QuicHpackDebugVisitor(); 47 QuicHpackDebugVisitor(const QuicHpackDebugVisitor&) = delete; 48 QuicHpackDebugVisitor& operator=(const QuicHpackDebugVisitor&) = delete; 49 50 virtual ~QuicHpackDebugVisitor(); 51 52 // For each HPACK indexed representation processed, |elapsed| is 53 // the time since the corresponding entry was added to the dynamic 54 // table. 55 virtual void OnUseEntry(QuicTime::Delta elapsed) = 0; 56 }; 57 58 class QUIC_EXPORT_PRIVATE Http3DebugVisitor { 59 public: 60 Http3DebugVisitor(); 61 Http3DebugVisitor(const Http3DebugVisitor&) = delete; 62 Http3DebugVisitor& operator=(const Http3DebugVisitor&) = delete; 63 64 virtual ~Http3DebugVisitor(); 65 66 // TODO(https://crbug.com/1062700): Remove default implementation of all 67 // methods after Chrome's QuicHttp3Logger has overrides. This is to make sure 68 // QUICHE merge is not blocked on having to add those overrides, they can 69 // happen asynchronously. 70 71 // Creation of unidirectional streams. 72 73 // Called when locally-initiated control stream is created. OnControlStreamCreated(QuicStreamId)74 virtual void OnControlStreamCreated(QuicStreamId /*stream_id*/) {} 75 // Called when locally-initiated QPACK encoder stream is created. OnQpackEncoderStreamCreated(QuicStreamId)76 virtual void OnQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) {} 77 // Called when locally-initiated QPACK decoder stream is created. OnQpackDecoderStreamCreated(QuicStreamId)78 virtual void OnQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) {} 79 // Called when peer's control stream type is received. 80 virtual void OnPeerControlStreamCreated(QuicStreamId /*stream_id*/) = 0; 81 // Called when peer's QPACK encoder stream type is received. 82 virtual void OnPeerQpackEncoderStreamCreated(QuicStreamId /*stream_id*/) = 0; 83 // Called when peer's QPACK decoder stream type is received. 84 virtual void OnPeerQpackDecoderStreamCreated(QuicStreamId /*stream_id*/) = 0; 85 86 // Incoming HTTP/3 frames on the control stream. OnCancelPushFrameReceived(const CancelPushFrame &)87 virtual void OnCancelPushFrameReceived(const CancelPushFrame& /*frame*/) {} 88 virtual void OnSettingsFrameReceived(const SettingsFrame& /*frame*/) = 0; OnGoAwayFrameReceived(const GoAwayFrame &)89 virtual void OnGoAwayFrameReceived(const GoAwayFrame& /*frame*/) {} OnMaxPushIdFrameReceived(const MaxPushIdFrame &)90 virtual void OnMaxPushIdFrameReceived(const MaxPushIdFrame& /*frame*/) {} OnPriorityUpdateFrameReceived(const PriorityUpdateFrame &)91 virtual void OnPriorityUpdateFrameReceived( 92 const PriorityUpdateFrame& /*frame*/) {} 93 94 // Incoming HTTP/3 frames on request or push streams. OnDataFrameReceived(QuicStreamId,QuicByteCount)95 virtual void OnDataFrameReceived(QuicStreamId /*stream_id*/, 96 QuicByteCount /*payload_length*/) {} OnHeadersFrameReceived(QuicStreamId,QuicByteCount)97 virtual void OnHeadersFrameReceived( 98 QuicStreamId /*stream_id*/, 99 QuicByteCount /*compressed_headers_length*/) {} OnHeadersDecoded(QuicStreamId,QuicHeaderList)100 virtual void OnHeadersDecoded(QuicStreamId /*stream_id*/, 101 QuicHeaderList /*headers*/) {} OnPushPromiseFrameReceived(QuicStreamId,QuicStreamId,QuicByteCount)102 virtual void OnPushPromiseFrameReceived(QuicStreamId /*stream_id*/, 103 QuicStreamId /*push_id*/, 104 QuicByteCount 105 /*compressed_headers_length*/) {} OnPushPromiseDecoded(QuicStreamId,QuicStreamId,QuicHeaderList)106 virtual void OnPushPromiseDecoded(QuicStreamId /*stream_id*/, 107 QuicStreamId /*push_id*/, 108 QuicHeaderList /*headers*/) {} 109 110 // Incoming HTTP/3 frames of unknown type on any stream. OnUnknownFrameReceived(QuicStreamId,uint64_t,QuicByteCount)111 virtual void OnUnknownFrameReceived(QuicStreamId /*stream_id*/, 112 uint64_t /*frame_type*/, 113 QuicByteCount /*payload_length*/) {} 114 115 // Outgoing HTTP/3 frames on the control stream. 116 virtual void OnSettingsFrameSent(const SettingsFrame& /*frame*/) = 0; OnGoAwayFrameSent(QuicStreamId)117 virtual void OnGoAwayFrameSent(QuicStreamId /*stream_id*/) {} OnMaxPushIdFrameSent(const MaxPushIdFrame &)118 virtual void OnMaxPushIdFrameSent(const MaxPushIdFrame& /*frame*/) {} OnPriorityUpdateFrameSent(const PriorityUpdateFrame &)119 virtual void OnPriorityUpdateFrameSent(const PriorityUpdateFrame& /*frame*/) { 120 } 121 122 // Outgoing HTTP/3 frames on request or push streams. OnDataFrameSent(QuicStreamId,QuicByteCount)123 virtual void OnDataFrameSent(QuicStreamId /*stream_id*/, 124 QuicByteCount /*payload_length*/) {} OnHeadersFrameSent(QuicStreamId,const spdy::SpdyHeaderBlock &)125 virtual void OnHeadersFrameSent( 126 QuicStreamId /*stream_id*/, 127 const spdy::SpdyHeaderBlock& /*header_block*/) {} OnPushPromiseFrameSent(QuicStreamId,QuicStreamId,const spdy::SpdyHeaderBlock &)128 virtual void OnPushPromiseFrameSent( 129 QuicStreamId /*stream_id*/, 130 QuicStreamId 131 /*push_id*/, 132 const spdy::SpdyHeaderBlock& /*header_block*/) {} 133 134 // 0-RTT related events. OnSettingsFrameResumed(const SettingsFrame &)135 virtual void OnSettingsFrameResumed(const SettingsFrame& /*frame*/) {} 136 }; 137 138 // A QUIC session for HTTP. 139 class QUIC_EXPORT_PRIVATE QuicSpdySession 140 : public QuicSession, 141 public QpackEncoder::DecoderStreamErrorDelegate, 142 public QpackDecoder::EncoderStreamErrorDelegate { 143 public: 144 // Does not take ownership of |connection| or |visitor|. 145 QuicSpdySession(QuicConnection* connection, 146 QuicSession::Visitor* visitor, 147 const QuicConfig& config, 148 const ParsedQuicVersionVector& supported_versions); 149 QuicSpdySession(const QuicSpdySession&) = delete; 150 QuicSpdySession& operator=(const QuicSpdySession&) = delete; 151 152 ~QuicSpdySession() override; 153 154 void Initialize() override; 155 156 // QpackEncoder::DecoderStreamErrorDelegate implementation. 157 void OnDecoderStreamError(QuicErrorCode error_code, 158 absl::string_view error_message) override; 159 160 // QpackDecoder::EncoderStreamErrorDelegate implementation. 161 void OnEncoderStreamError(QuicErrorCode error_code, 162 absl::string_view error_message) override; 163 164 // Called by |headers_stream_| when headers with a priority have been 165 // received for a stream. This method will only be called for server streams. 166 virtual void OnStreamHeadersPriority( 167 QuicStreamId stream_id, 168 const spdy::SpdyStreamPrecedence& precedence); 169 170 // Called by |headers_stream_| when headers have been completely received 171 // for a stream. |fin| will be true if the fin flag was set in the headers 172 // frame. 173 virtual void OnStreamHeaderList(QuicStreamId stream_id, 174 bool fin, 175 size_t frame_len, 176 const QuicHeaderList& header_list); 177 178 // Called by |headers_stream_| when push promise headers have been 179 // completely received. |fin| will be true if the fin flag was set 180 // in the headers. 181 virtual void OnPromiseHeaderList(QuicStreamId stream_id, 182 QuicStreamId promised_stream_id, 183 size_t frame_len, 184 const QuicHeaderList& header_list); 185 186 // Called by |headers_stream_| when a PRIORITY frame has been received for a 187 // stream. This method will only be called for server streams. 188 virtual void OnPriorityFrame(QuicStreamId stream_id, 189 const spdy::SpdyStreamPrecedence& precedence); 190 191 // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a request 192 // stream. Returns false and closes connection if |stream_id| is invalid. 193 bool OnPriorityUpdateForRequestStream(QuicStreamId stream_id, int urgency); 194 195 // Called when an HTTP/3 PRIORITY_UPDATE frame has been received for a push 196 // stream. Returns false and closes connection if |push_id| is invalid. 197 bool OnPriorityUpdateForPushStream(QuicStreamId push_id, int urgency); 198 199 // Sends contents of |iov| to h2_deframer_, returns number of bytes processed. 200 size_t ProcessHeaderData(const struct iovec& iov); 201 202 // Writes |headers| for the stream |id| to the dedicated headers stream. 203 // If |fin| is true, then no more data will be sent for the stream |id|. 204 // If provided, |ack_notifier_delegate| will be registered to be notified when 205 // we have seen ACKs for all packets resulting from this call. 206 virtual size_t WriteHeadersOnHeadersStream( 207 QuicStreamId id, 208 spdy::SpdyHeaderBlock headers, 209 bool fin, 210 const spdy::SpdyStreamPrecedence& precedence, 211 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); 212 213 // Writes an HTTP/2 PRIORITY frame the to peer. Returns the size in bytes of 214 // the resulting PRIORITY frame. 215 size_t WritePriority(QuicStreamId id, 216 QuicStreamId parent_stream_id, 217 int weight, 218 bool exclusive); 219 220 // Writes an HTTP/3 PRIORITY_UPDATE frame to the peer. 221 void WriteHttp3PriorityUpdate(const PriorityUpdateFrame& priority_update); 222 223 // Process received HTTP/3 GOAWAY frame. When sent from server to client, 224 // |id| is a stream ID. When sent from client to server, |id| is a push ID. 225 virtual void OnHttp3GoAway(uint64_t id); 226 227 // Send GOAWAY if the peer is blocked on the implementation max. 228 bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override; 229 230 // Write GOAWAY frame with maximum stream ID on the control stream. Called to 231 // initite graceful connection shutdown. Do not use smaller stream ID, in 232 // case client does not implement retry on GOAWAY. Do not send GOAWAY if one 233 // has already been sent. 234 void SendHttp3GoAway(); 235 236 // Same as SendHttp3GoAway(). TODO(bnc): remove when 237 // gfe2_reloadable_flag_quic_goaway_with_max_stream_id flag is deprecated. 238 void SendHttp3Shutdown(); 239 240 // Write |headers| for |promised_stream_id| on |original_stream_id| in a 241 // PUSH_PROMISE frame to peer. 242 virtual void WritePushPromise(QuicStreamId original_stream_id, 243 QuicStreamId promised_stream_id, 244 spdy::SpdyHeaderBlock headers); 245 246 QpackEncoder* qpack_encoder(); 247 QpackDecoder* qpack_decoder(); headers_stream()248 QuicHeadersStream* headers_stream() { return headers_stream_; } 249 headers_stream()250 const QuicHeadersStream* headers_stream() const { return headers_stream_; } 251 252 // Returns whether server push is enabled. 253 // For a Google QUIC client this always returns false. 254 // For a Google QUIC server this is set by incoming SETTINGS_ENABLE_PUSH. 255 // For an IETF QUIC client this returns true if SetMaxPushId() has ever been 256 // called. 257 // For an IETF QUIC server this returns true if EnableServerPush() has been 258 // called and the server has received at least one MAX_PUSH_ID frame from the 259 // client. 260 bool server_push_enabled() const; 261 262 // Called when the control stream receives HTTP/3 SETTINGS. 263 // Returns false in case of 0-RTT if received settings are incompatible with 264 // cached values, true otherwise. 265 virtual bool OnSettingsFrame(const SettingsFrame& frame); 266 267 // Called when a SETTINGS is parsed from an incoming SETTINGS frame. 268 // Returns false in case of 0-RTT if received SETTINGS is incompatible with 269 // cached value, true otherwise. 270 bool OnSetting(uint64_t id, uint64_t value); 271 272 // Return true if this session wants to release headers stream's buffer 273 // aggressively. 274 virtual bool ShouldReleaseHeadersStreamSequencerBuffer(); 275 276 void CloseConnectionWithDetails(QuicErrorCode error, 277 const std::string& details); 278 279 // Must not be called after Initialize(). 280 // TODO(bnc): Move to constructor argument. set_qpack_maximum_dynamic_table_capacity(uint64_t qpack_maximum_dynamic_table_capacity)281 void set_qpack_maximum_dynamic_table_capacity( 282 uint64_t qpack_maximum_dynamic_table_capacity) { 283 qpack_maximum_dynamic_table_capacity_ = 284 qpack_maximum_dynamic_table_capacity; 285 } 286 287 // Must not be called after Initialize(). 288 // TODO(bnc): Move to constructor argument. set_qpack_maximum_blocked_streams(uint64_t qpack_maximum_blocked_streams)289 void set_qpack_maximum_blocked_streams( 290 uint64_t qpack_maximum_blocked_streams) { 291 qpack_maximum_blocked_streams_ = qpack_maximum_blocked_streams; 292 } 293 294 // Must not be called after Initialize(). 295 // TODO(bnc): Move to constructor argument. set_max_inbound_header_list_size(size_t max_inbound_header_list_size)296 void set_max_inbound_header_list_size(size_t max_inbound_header_list_size) { 297 max_inbound_header_list_size_ = max_inbound_header_list_size; 298 } 299 max_outbound_header_list_size()300 size_t max_outbound_header_list_size() const { 301 return max_outbound_header_list_size_; 302 } 303 max_inbound_header_list_size()304 size_t max_inbound_header_list_size() const { 305 return max_inbound_header_list_size_; 306 } 307 308 // Returns true if the session has active request streams. 309 bool HasActiveRequestStreams() const; 310 311 // Called when the size of the compressed frame payload is available. 312 void OnCompressedFrameSize(size_t frame_len); 313 314 // Called when a PUSH_PROMISE frame has been received. 315 void OnPushPromise(spdy::SpdyStreamId stream_id, 316 spdy::SpdyStreamId promised_stream_id); 317 318 // Called when the complete list of headers is available. 319 void OnHeaderList(const QuicHeaderList& header_list); 320 promised_stream_id()321 QuicStreamId promised_stream_id() const { return promised_stream_id_; } 322 323 // Initialze HTTP/3 unidirectional streams if |unidirectional| is true and 324 // those streams are not initialized yet. 325 void OnCanCreateNewOutgoingStream(bool unidirectional) override; 326 327 // Sets |max_push_id_| and sends a MAX_PUSH_ID frame. 328 // This method must only be called if protocol is IETF QUIC and perspective is 329 // client. |max_push_id| must be greater than or equal to current 330 // |max_push_id_|. 331 void SetMaxPushId(PushId max_push_id); 332 333 // Sets |max_push_id_|. 334 // This method must only be called if protocol is IETF QUIC and perspective is 335 // server. It must only be called if a MAX_PUSH_ID frame is received. 336 // Returns whether |max_push_id| is greater than or equal to current 337 // |max_push_id_|. 338 bool OnMaxPushIdFrame(PushId max_push_id); 339 340 // Enables server push. 341 // Must only be called when using IETF QUIC, for which server push is disabled 342 // by default. Server push defaults to enabled and cannot be disabled for 343 // Google QUIC. 344 // Must only be called for a server. A client can effectively disable push by 345 // never calling SetMaxPushId(). 346 void EnableServerPush(); 347 348 // Returns true if push is enabled and a push with |push_id| can be created. 349 // For a server this means that EnableServerPush() has been called, at least 350 // one MAX_PUSH_ID frame has been received, and the largest received 351 // MAX_PUSH_ID value is greater than or equal to |push_id|. 352 // For a client this means that SetMaxPushId() has been called with 353 // |max_push_id| greater than or equal to |push_id|. 354 // Must only be called when using IETF QUIC. 355 bool CanCreatePushStreamWithId(PushId push_id); 356 destruction_indicator()357 int32_t destruction_indicator() const { return destruction_indicator_; } 358 set_debug_visitor(Http3DebugVisitor * debug_visitor)359 void set_debug_visitor(Http3DebugVisitor* debug_visitor) { 360 debug_visitor_ = debug_visitor; 361 } 362 debug_visitor()363 Http3DebugVisitor* debug_visitor() { return debug_visitor_; } 364 365 // When using Google QUIC, return whether a transport layer GOAWAY frame has 366 // been received or sent. 367 // When using IETF QUIC, return whether an HTTP/3 GOAWAY frame has been 368 // received or sent. 369 bool goaway_received() const; 370 bool goaway_sent() const; 371 372 // Log header compression ratio histogram. 373 // |using_qpack| is true for QPACK, false for HPACK. 374 // |is_sent| is true for sent headers, false for received ones. 375 // Ratio is recorded as percentage. Smaller value means more efficient 376 // compression. Compressed size might be larger than uncompressed size, but 377 // recorded ratio is trunckated at 200%. 378 // Uncompressed size can be zero for an empty header list, and compressed size 379 // can be zero for an empty header list when using HPACK. (QPACK always emits 380 // a header block prefix of at least two bytes.) This method records nothing 381 // if either |compressed| or |uncompressed| is not positive. 382 // In order for measurements for different protocol to be comparable, the 383 // caller must ensure that uncompressed size is the total length of header 384 // names and values without any overhead. 385 static void LogHeaderCompressionRatioHistogram(bool using_qpack, 386 bool is_sent, 387 QuicByteCount compressed, 388 QuicByteCount uncompressed); 389 390 // True if any dynamic table entries have been referenced from either a sent 391 // or received header block. Used for stats. dynamic_table_entry_referenced()392 bool dynamic_table_entry_referenced() const { 393 return (qpack_encoder_ && 394 qpack_encoder_->dynamic_table_entry_referenced()) || 395 (qpack_decoder_ && qpack_decoder_->dynamic_table_entry_referenced()); 396 } 397 398 void OnStreamCreated(QuicSpdyStream* stream); 399 400 // Decode SETTINGS from |cached_state| and apply it to the session. 401 bool ResumeApplicationState(ApplicationState* cached_state) override; 402 403 protected: 404 // Override CreateIncomingStream(), CreateOutgoingBidirectionalStream() and 405 // CreateOutgoingUnidirectionalStream() with QuicSpdyStream return type to 406 // make sure that all data streams are QuicSpdyStreams. 407 QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override = 0; 408 QuicSpdyStream* CreateIncomingStream(PendingStream* pending) override = 0; 409 virtual QuicSpdyStream* CreateOutgoingBidirectionalStream() = 0; 410 virtual QuicSpdyStream* CreateOutgoingUnidirectionalStream() = 0; 411 412 QuicSpdyStream* GetOrCreateSpdyDataStream(const QuicStreamId stream_id); 413 414 // If an incoming stream can be created, return true. 415 virtual bool ShouldCreateIncomingStream(QuicStreamId id) = 0; 416 417 // If an outgoing bidirectional/unidirectional stream can be created, return 418 // true. 419 virtual bool ShouldCreateOutgoingBidirectionalStream() = 0; 420 virtual bool ShouldCreateOutgoingUnidirectionalStream() = 0; 421 422 // Returns true if there are open HTTP requests. 423 bool ShouldKeepConnectionAlive() const override; 424 425 // Overridden to buffer incoming unidirectional streams for version 99. 426 bool UsesPendingStreams() const override; 427 428 // Overridden to Process HTTP/3 stream types. H/3 streams will be created from 429 // pending streams accordingly if the stream type can be read. Returns true if 430 // unidirectional streams are created. 431 bool ProcessPendingStream(PendingStream* pending) override; 432 433 size_t WriteHeadersOnHeadersStreamImpl( 434 QuicStreamId id, 435 spdy::SpdyHeaderBlock headers, 436 bool fin, 437 QuicStreamId parent_stream_id, 438 int weight, 439 bool exclusive, 440 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); 441 442 void OnNewEncryptionKeyAvailable( 443 EncryptionLevel level, 444 std::unique_ptr<QuicEncrypter> encrypter) override; 445 446 // Optional, enables instrumentation related to go/quic-hpack. 447 void SetHpackEncoderDebugVisitor( 448 std::unique_ptr<QuicHpackDebugVisitor> visitor); 449 void SetHpackDecoderDebugVisitor( 450 std::unique_ptr<QuicHpackDebugVisitor> visitor); 451 452 // Sets the maximum size of the header compression table spdy_framer_ is 453 // willing to use to encode header blocks. 454 void UpdateHeaderEncoderTableSize(uint32_t value); 455 456 // Called when SETTINGS_ENABLE_PUSH is received, only supported on 457 // server side. 458 void UpdateEnableServerPush(bool value); 459 IsConnected()460 bool IsConnected() { return connection()->connected(); } 461 receive_control_stream()462 const QuicReceiveControlStream* receive_control_stream() const { 463 return receive_control_stream_; 464 } 465 settings()466 const SettingsFrame& settings() const { return settings_; } 467 468 // Initializes HTTP/3 unidirectional streams if not yet initialzed. 469 virtual void MaybeInitializeHttp3UnidirectionalStreams(); 470 471 // QuicConnectionVisitorInterface method. 472 void BeforeConnectionCloseSent() override; 473 474 private: 475 friend class test::QuicSpdySessionPeer; 476 477 class SpdyFramerVisitor; 478 479 // The following methods are called by the SimpleVisitor. 480 481 // Called when a HEADERS frame has been received. 482 void OnHeaders(spdy::SpdyStreamId stream_id, 483 bool has_priority, 484 const spdy::SpdyStreamPrecedence& precedence, 485 bool fin); 486 487 // Called when a PRIORITY frame has been received. 488 void OnPriority(spdy::SpdyStreamId stream_id, 489 const spdy::SpdyStreamPrecedence& precedence); 490 491 void CloseConnectionOnDuplicateHttp3UnidirectionalStreams( 492 absl::string_view type); 493 494 // Sends any data which should be sent at the start of a connection, including 495 // the initial SETTINGS frame, and (when IETF QUIC is used) also a MAX_PUSH_ID 496 // frame if SetMaxPushId() had been called before encryption was established. 497 // When using 0-RTT, this method is called twice: once when encryption is 498 // established, and again when 1-RTT keys are available. 499 void SendInitialData(); 500 501 // Send a MAX_PUSH_ID frame. Used in IETF QUIC only. 502 void SendMaxPushId(); 503 504 void FillSettingsFrame(); 505 506 std::unique_ptr<QpackEncoder> qpack_encoder_; 507 std::unique_ptr<QpackDecoder> qpack_decoder_; 508 509 // Pointer to the header stream in stream_map_. 510 QuicHeadersStream* headers_stream_; 511 512 // HTTP/3 control streams. They are owned by QuicSession inside 513 // stream map, and can be accessed by those unowned pointers below. 514 QuicSendControlStream* send_control_stream_; 515 QuicReceiveControlStream* receive_control_stream_; 516 517 // Pointers to HTTP/3 QPACK streams in stream map. 518 QpackReceiveStream* qpack_encoder_receive_stream_; 519 QpackReceiveStream* qpack_decoder_receive_stream_; 520 QpackSendStream* qpack_encoder_send_stream_; 521 QpackSendStream* qpack_decoder_send_stream_; 522 523 SettingsFrame settings_; 524 525 // Maximum dynamic table capacity as defined at 526 // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#maximum-dynamic-table-capacity 527 // for the decoding context. Value will be sent via 528 // SETTINGS_QPACK_MAX_TABLE_CAPACITY. 529 // |qpack_maximum_dynamic_table_capacity_| also serves as an upper bound for 530 // the dynamic table capacity of the encoding context, to limit memory usage 531 // if a larger SETTINGS_QPACK_MAX_TABLE_CAPACITY value is received. 532 uint64_t qpack_maximum_dynamic_table_capacity_; 533 534 // Maximum number of blocked streams as defined at 535 // https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#blocked-streams 536 // for the decoding context. Value will be sent via 537 // SETTINGS_QPACK_BLOCKED_STREAMS. 538 uint64_t qpack_maximum_blocked_streams_; 539 540 // The maximum size of a header block that will be accepted from the peer, 541 // defined per spec as key + value + overhead per field (uncompressed). 542 // Value will be sent via SETTINGS_MAX_HEADER_LIST_SIZE. 543 size_t max_inbound_header_list_size_; 544 545 // The maximum size of a header block that can be sent to the peer. This field 546 // is informed and set by the peer via SETTINGS frame. 547 // TODO(b/148616439): Honor this field when sending headers. 548 size_t max_outbound_header_list_size_; 549 550 // Data about the stream whose headers are being processed. 551 QuicStreamId stream_id_; 552 QuicStreamId promised_stream_id_; 553 size_t frame_len_; 554 bool fin_; 555 556 spdy::SpdyFramer spdy_framer_; 557 http2::Http2DecoderAdapter h2_deframer_; 558 std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_; 559 560 // Used in IETF QUIC only. 561 // For a server: 562 // the push ID in the most recently received MAX_PUSH_ID frame, 563 // or unset if no MAX_PUSH_ID frame has been received. 564 // For a client: 565 // unset until SetMaxPushId() is called; 566 // before encryption is established, the push ID to be sent in the initial 567 // MAX_PUSH_ID frame; 568 // after encryption is established, the push ID in the most recently sent 569 // MAX_PUSH_ID frame. 570 // Once set, never goes back to unset. 571 absl::optional<PushId> max_push_id_; 572 573 // Not owned by the session. 574 Http3DebugVisitor* debug_visitor_; 575 576 // Priority values received in PRIORITY_UPDATE frames for streams that are not 577 // open yet. 578 QuicHashMap<QuicStreamId, int> buffered_stream_priorities_; 579 580 // An integer used for live check. The indicator is assigned a value in 581 // constructor. As long as it is not the assigned value, that would indicate 582 // an use-after-free. 583 int32_t destruction_indicator_; 584 585 // Used in Google QUIC only. Set every time SETTINGS_ENABLE_PUSH is received. 586 // Defaults to true. 587 bool server_push_enabled_; 588 589 // Used in IETF QUIC only. Defaults to false. 590 // Server push is enabled for a server by calling EnableServerPush(). 591 // Server push is enabled for a client by calling SetMaxPushId(). 592 bool ietf_server_push_enabled_; 593 594 // The identifier in the most recently received GOAWAY frame. Unset if no 595 // GOAWAY frame has been received yet. 596 absl::optional<uint64_t> last_received_http3_goaway_id_; 597 // The identifier in the most recently sent GOAWAY frame. Unset if no GOAWAY 598 // frame has been sent yet. 599 absl::optional<uint64_t> last_sent_http3_goaway_id_; 600 601 // Only used by a client, only with IETF QUIC. True if a MAX_PUSH_ID frame 602 // has been sent, in which case |max_push_id_| has the value sent in the most 603 // recent MAX_PUSH_ID frame. Once true, never goes back to false. 604 bool http3_max_push_id_sent_; 605 606 // Latched value of reloadable flag quic_reject_spdy_settings. 607 const bool reject_spdy_settings_; 608 609 // Latched value of reloadable flag quic_goaway_with_max_stream_id. 610 const bool goaway_with_max_stream_id_; 611 }; 612 613 } // namespace quic 614 615 #endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_SESSION_H_ 616