Index: net/quic/core/quic_spdy_session.h |
diff --git a/net/quic/core/quic_spdy_session.h b/net/quic/core/quic_spdy_session.h |
index 73e5405443f477e646f4fbf1234f589e128ccb11..d0066b59ebe64264a09f36c3a297636335887c6d 100644 |
--- a/net/quic/core/quic_spdy_session.h |
+++ b/net/quic/core/quic_spdy_session.h |
@@ -22,6 +22,26 @@ namespace test { |
class QuicSpdySessionPeer; |
} // namespace test |
+// QuicHpackDebugVisitor gathers data used for understanding HPACK HoL |
+// dynamics. Specifically, it is to help predict the compression |
+// penalty of avoiding HoL by chagning how the dynamic table is used. |
+// In chromium, the concrete instance populates an UMA |
+// histogram with the data. |
+class QUIC_EXPORT_PRIVATE QuicHpackDebugVisitor { |
+ public: |
+ QuicHpackDebugVisitor(); |
+ |
+ virtual ~QuicHpackDebugVisitor(); |
+ |
+ // For each HPACK indexed representation processed, |elapsed| is |
+ // the time since the corresponding entry was added to the dynamic |
+ // table. |
+ virtual void OnUseEntry(QuicTime::Delta elapsed) = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(QuicHpackDebugVisitor); |
+}; |
+ |
// A QUIC session with a headers stream. |
class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
public: |
@@ -56,6 +76,9 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
size_t frame_len, |
const QuicHeaderList& header_list); |
+ // Sends contents of |iov| to spdy_framer_, returns number of bytes processd. |
+ size_t ProcessHeaderData(const struct iovec& iov, QuicTime timestamp); |
+ |
// Writes |headers| for the stream |id| to the dedicated headers stream. |
// If |fin| is true, then no more data will be sent for the stream |id|. |
// If provided, |ack_notifier_delegate| will be registered to be notified when |
@@ -67,6 +90,25 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
SpdyPriority priority, |
QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
+ // Write |headers| for |promised_stream_id| on |original_stream_id| in a |
+ // PUSH_PROMISE frame to peer. |
+ // Return the size, in bytes, of the resulting PUSH_PROMISE frame. |
+ virtual size_t WritePushPromise(QuicStreamId original_stream_id, |
+ QuicStreamId promised_stream_id, |
+ SpdyHeaderBlock headers); |
+ |
+ // For forcing HOL blocking. This encapsulates data from other |
+ // streams into HTTP/2 data frames on the headers stream. |
+ QuicConsumedData WritevStreamData( |
+ QuicStreamId id, |
+ QuicIOVector iov, |
+ QuicStreamOffset offset, |
+ bool fin, |
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
+ |
+ // Sends SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame. |
+ size_t SendMaxHeaderListSize(size_t value); |
+ |
QuicHeadersStream* headers_stream() { return headers_stream_.get(); } |
// Called when Head of Line Blocking happens in the headers stream. |
@@ -94,6 +136,10 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
bool server_push_enabled() const { return server_push_enabled_; } |
+ void UpdateCurMaxTimeStamp(QuicTime timestamp) { |
+ cur_max_timestamp_ = std::max(timestamp, cur_max_timestamp_); |
+ } |
+ |
// Called by |QuicHeadersStream::UpdateEnableServerPush()| with |
// value from SETTINGS_ENABLE_PUSH. |
void set_server_push_enabled(bool enable) { server_push_enabled_ = enable; } |
@@ -102,6 +148,17 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
// aggressively. |
virtual bool ShouldReleaseHeadersStreamSequencerBuffer(); |
+ SpdyFramer* spdy_framer() { return &spdy_framer_; } |
+ |
+ void CloseConnectionWithDetails(QuicErrorCode error, |
+ const std::string& details); |
+ |
+ // Sets how much encoded data the hpack decoder of spdy_framer_ is willing to |
+ // buffer. |
+ void set_max_decode_buffer_size_bytes(size_t max_decode_buffer_size_bytes) { |
+ spdy_framer_.set_max_decode_buffer_size_bytes(max_decode_buffer_size_bytes); |
+ } |
+ |
protected: |
// Override CreateIncomingDynamicStream() and CreateOutgoingDynamicStream() |
// with QuicSpdyStream return type to make sure that all data streams are |
@@ -120,9 +177,79 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; |
+ bool supports_push_promise() { return supports_push_promise_; } |
+ |
+ // Experimental: force HPACK to use static table and huffman coding |
+ // only. Part of exploring improvements related to headers stream |
+ // induced HOL blocking in QUIC. |
+ void DisableHpackDynamicTable(); |
+ |
+ // Optional, enables instrumentation related to go/quic-hpack. |
+ void SetHpackEncoderDebugVisitor( |
+ std::unique_ptr<QuicHpackDebugVisitor> visitor); |
+ void SetHpackDecoderDebugVisitor( |
+ std::unique_ptr<QuicHpackDebugVisitor> visitor); |
+ |
+ // Sets the maximum size of the header compression table spdy_framer_ is |
+ // willing to use to decode header blocks. |
+ void UpdateHeaderEncoderTableSize(uint32_t value); |
+ |
+ // Called when SETTINGS_ENABLE_PUSH is received, only supported on |
+ // server side. |
+ void UpdateEnableServerPush(bool value); |
+ |
+ void set_max_uncompressed_header_bytes( |
+ size_t set_max_uncompressed_header_bytes); |
+ |
+ bool IsConnected() { return connection()->connected(); } |
+ |
private: |
friend class test::QuicSpdySessionPeer; |
+ class SpdyFramerVisitor; |
+ |
+ // The following methods are called by the SimpleVisitor. |
+ |
+ // Called when a HEADERS frame has been received. |
+ void OnHeaders(SpdyStreamId stream_id, |
+ bool has_priority, |
+ SpdyPriority priority, |
+ bool fin); |
+ |
+ // Called when a PUSH_PROMISE frame has been received. |
+ void OnPushPromise(SpdyStreamId stream_id, |
+ SpdyStreamId promised_stream_id, |
+ bool end); |
+ |
+ // Called when the complete list of headers is available. |
+ void OnHeaderList(const QuicHeaderList& header_list); |
+ |
+ // Called when the size of the compressed frame payload is available. |
+ void OnCompressedFrameSize(size_t frame_len); |
+ |
+ // For force HOL blocking, where stream frames from all streams are |
+ // plumbed through headers stream as HTTP/2 data frames. |
+ // The following two return false if force_hol_blocking_ is false. |
+ bool OnDataFrameHeader(QuicStreamId stream_id, size_t length, bool fin); |
+ bool OnStreamFrameData(QuicStreamId stream_id, const char* data, size_t len); |
+ |
+ // Helper for |WritevStreamData()|. |
+ void WriteDataFrame( |
+ QuicStreamId stream_id, |
+ base::StringPiece data, |
+ bool fin, |
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
+ |
+ // This was formerly QuicHeadersStream::WriteHeaders. Needs to be |
+ // separate from QuicSpdySession::WriteHeaders because tests call |
+ // this but mock the latter. |
+ size_t WriteHeadersImpl( |
+ QuicStreamId id, |
+ SpdyHeaderBlock headers, |
+ bool fin, |
+ SpdyPriority priority, |
+ QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener); |
+ |
std::unique_ptr<QuicHeadersStream> headers_stream_; |
// If set, redirect all data through the headers stream in order to |
@@ -134,6 +261,27 @@ class QUIC_EXPORT_PRIVATE QuicSpdySession : public QuicSession { |
// headers will be pushed. |
bool server_push_enabled_; |
+ // Data about the stream whose headers are being processed. |
+ QuicStreamId stream_id_; |
+ QuicStreamId promised_stream_id_; |
+ bool fin_; |
+ size_t frame_len_; |
+ size_t uncompressed_frame_len_; |
+ |
+ bool supports_push_promise_; |
+ |
+ // Timestamps used to measure HOL blocking, these are recorded by |
+ // the sequencer approximate to the time of arrival off the wire. |
+ // |cur_max_timestamp_| tracks the most recent arrival time of |
+ // frames for current (at the headers stream level) processed |
+ // stream's headers, and |prev_max_timestamp_| tracks the most |
+ // recent arrival time of lower numbered streams. |
+ QuicTime cur_max_timestamp_; |
+ QuicTime prev_max_timestamp_; |
+ |
+ SpdyFramer spdy_framer_; |
+ std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_; |
+ |
DISALLOW_COPY_AND_ASSIGN(QuicSpdySession); |
}; |