Index: net/quic/core/quic_spdy_session.cc |
diff --git a/net/quic/core/quic_spdy_session.cc b/net/quic/core/quic_spdy_session.cc |
index 77cd2cbb6800c798691ee80d1992ac3ac0f8fc89..26d6d3cdbb2138e172c2b4496a00c4f6a7c78183 100644 |
--- a/net/quic/core/quic_spdy_session.cc |
+++ b/net/quic/core/quic_spdy_session.cc |
@@ -11,9 +11,11 @@ |
#include "net/quic/core/quic_headers_stream.h" |
#include "net/quic/platform/api/quic_bug_tracker.h" |
+#include "net/quic/platform/api/quic_flag_utils.h" |
#include "net/quic/platform/api/quic_flags.h" |
#include "net/quic/platform/api/quic_logging.h" |
#include "net/quic/platform/api/quic_str_cat.h" |
+#include "net/quic/platform/api/quic_text_utils.h" |
using std::string; |
@@ -393,7 +395,35 @@ void QuicSpdySession::OnStreamHeaderList(QuicStreamId stream_id, |
size_t frame_len, |
const QuicHeaderList& header_list) { |
QuicSpdyStream* stream = GetSpdyDataStream(stream_id); |
- if (!stream) { |
+ if (stream == nullptr) { |
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_final_offset_from_trailers, 1, |
+ 3); |
+ if (FLAGS_quic_reloadable_flag_quic_final_offset_from_trailers) { |
+ QUIC_FLAG_COUNT_N(quic_reloadable_flag_quic_final_offset_from_trailers, 2, |
+ 3); |
+ // The stream no longer exists, but trailing headers may contain the final |
+ // byte offset necessary for flow control and open stream accounting. |
+ size_t final_byte_offset = 0; |
+ for (const auto& header : header_list) { |
+ const string& header_key = header.first; |
+ const string& header_value = header.second; |
+ if (header_key == kFinalOffsetHeaderKey) { |
+ if (!QuicTextUtils::StringToSizeT(header_value, &final_byte_offset)) { |
+ connection()->CloseConnection( |
+ QUIC_INVALID_HEADERS_STREAM_DATA, |
+ "Trailers are malformed (no final offset)", |
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
+ return; |
+ } |
+ DVLOG(1) << "Received final byte offset in trailers for stream " |
+ << stream_id << ", which no longer exists."; |
+ OnFinalByteOffsetReceived(stream_id, final_byte_offset); |
+ QUIC_FLAG_COUNT_N( |
+ quic_reloadable_flag_quic_final_offset_from_trailers, 3, 3); |
+ } |
+ } |
+ } |
+ |
// It's quite possible to receive headers after a stream has been reset. |
return; |
} |