quic_data_stream.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_data_stream.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_session.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_spdy_decompressor.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_write_blocked_list.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece; 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using std::min; 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net { 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ENDPOINT (session()->is_server() ? "Server: " : " Client: ") 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is somewhat arbitrary. It's possible, but unlikely, we will either fail 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// to set a priority client-side, or cancel a stream before stripping the 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// priority from the wire server-side. In either case, start out with a 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// priority in the middle. 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicPriority kDefaultPriority = 3; 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Appends bytes from data into partial_data_buffer. Once partial_data_buffer 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// reaches 4 bytes, copies the data into 'result' and clears 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// partial_data_buffer. 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns the number of bytes consumed. 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 StripUint32(const char* data, uint32 data_len, 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) string* partial_data_buffer, 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32* result) { 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_GT(4u, partial_data_buffer->length()); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t missing_size = 4 - partial_data_buffer->length(); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data_len < missing_size) { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(data, data_len).AppendToString(partial_data_buffer); 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return data_len; 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(data, missing_size).AppendToString(partial_data_buffer); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(4u, partial_data_buffer->length()); 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(result, partial_data_buffer->data(), 4); 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) partial_data_buffer->clear(); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return missing_size; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicDataStream::QuicDataStream(QuicStreamId id, 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicSession* session) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ReliableQuicStream(id, session), 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_(NULL), 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_decompressed_(false), 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_(kDefaultPriority), 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_id_(0), 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompression_failed_(false), 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_parsed_(false) { 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(kCryptoStreamId, id); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (version() > QUIC_VERSION_12) { 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't receive any callbacks from the sequencer until headers 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are complete. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->SetBlockedUntilFlush(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicDataStream::~QuicDataStream() { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)size_t QuicDataStream::WriteHeaders(const SpdyHeaderBlock& header_block, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) { 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_written = session()->WriteHeaders(id(), header_block, fin); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(rch): Add test to ensure fin_sent_ is set whenever a fin is sent. 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_fin_sent(true); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseWriteSide(); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bytes_written; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)size_t QuicDataStream::Readv(const struct iovec* iov, size_t iov_len) { 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FinishedReadingHeaders()) { 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the headers have been read, simply delegate to the sequencer's 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Readv method. 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return sequencer()->Readv(iov, iov_len); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Otherwise, copy decompressed header data into |iov|. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_consumed = 0; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t iov_index = 0; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (iov_index < iov_len && 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.length() > bytes_consumed) { 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_to_read = min(iov[iov_index].iov_len, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.length() - bytes_consumed); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memcpy(iov_ptr, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.data() + bytes_consumed, bytes_to_read); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bytes_consumed += bytes_to_read; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++iov_index; 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.erase(0, bytes_consumed); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FinishedReadingHeaders()) { 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->FlushBufferedFrames(); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bytes_consumed; 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int QuicDataStream::GetReadableRegions(iovec* iov, size_t iov_len) { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FinishedReadingHeaders()) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return sequencer()->GetReadableRegions(iov, iov_len); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (iov_len == 0) { 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iov[0].iov_base = static_cast<void*>( 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const_cast<char*>(decompressed_headers_.data())); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iov[0].iov_len = decompressed_headers_.length(); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 1; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDataStream::IsDoneReading() const { 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!headers_decompressed_ || !decompressed_headers_.empty()) { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return sequencer()->IsClosed(); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDataStream::HasBytesToRead() const { 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return !decompressed_headers_.empty() || sequencer()->HasBytesToRead(); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::set_priority(QuicPriority priority) { 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, stream_bytes_written()); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_ = priority; 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicPriority QuicDataStream::EffectivePriority() const { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return priority(); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 QuicDataStream::ProcessRawData(const char* data, uint32 data_len) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (version() <= QUIC_VERSION_12) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ProcessRawData12(data, data_len); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!FinishedReadingHeaders()) { 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "ProcessRawData called before headers have been finished"; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ProcessData(data, data_len); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 QuicDataStream::ProcessRawData12(const char* data, uint32 data_len) { 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, data_len); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 total_bytes_consumed = 0; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (headers_id_ == 0u) { 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_consumed += StripPriorityAndHeaderId(data, data_len); 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data += total_bytes_consumed; 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data_len -= total_bytes_consumed; 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data_len == 0 || total_bytes_consumed == 0) { 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, headers_id_); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Once the headers are finished, we simply pass the data through. 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (headers_decompressed_) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Some buffered header data remains. 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!decompressed_headers_.empty()) { 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessHeaderData(); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (decompressed_headers_.empty()) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Delegating procesing to ProcessData"; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_consumed += ProcessData(data, data_len); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicHeaderId current_header_id = 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->decompressor()->current_header_id(); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure that this header id looks sane. 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (headers_id_ < current_header_id || 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_id_ > kMaxHeaderIdDelta + current_header_id) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Invalid headers for stream: " << id() 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " header_id: " << headers_id_ 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " current_header_id: " << current_header_id; 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->connection()->SendConnectionClose(QUIC_INVALID_HEADER_ID); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we are head-of-line blocked on decompression, then back up. 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (current_header_id != headers_id_) { 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->MarkDecompressionBlocked(headers_id_, id()); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << ENDPOINT 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Unable to decompress header data for stream: " << id() 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " header_id: " << headers_id_; 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Decompressed data will be delivered to decompressed_headers_. 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_consumed = session()->decompressor()->DecompressData( 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(data, data_len), this); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, bytes_consumed); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (bytes_consumed > data_len) { 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(false) << "DecompressData returned illegal value"; 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnDecompressionError(); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_consumed += bytes_consumed; 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data += bytes_consumed; 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data_len -= bytes_consumed; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (decompression_failed_) { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The session will have been closed in OnDecompressionError. 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Headers are complete if the decompressor has moved on to the 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // next stream. 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_decompressed_ = 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->decompressor()->current_header_id() != headers_id_; 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!headers_decompressed_) { 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, data_len); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessHeaderData(); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!headers_decompressed_ || !decompressed_headers_.empty()) { 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We have processed all of the decompressed data but we might 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // have some more raw data to process. 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data_len > 0) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_consumed += ProcessData(data, data_len); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The sequencer will push any additional buffered frames if this data 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // has been completely consumed. 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_consumed; 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const IPEndPoint& QuicDataStream::GetPeerAddress() { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->peer_address(); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSpdyCompressor* QuicDataStream::compressor() { 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->compressor(); 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDataStream::GetSSLInfo(SSLInfo* ssl_info) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->GetSSLInfo(ssl_info); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 QuicDataStream::ProcessHeaderData() { 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (decompressed_headers_.empty()) { 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_processed = ProcessData(decompressed_headers_.data(), 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.length()); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (bytes_processed == decompressed_headers_.length()) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_.clear(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompressed_headers_ = decompressed_headers_.erase(0, bytes_processed); 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return bytes_processed; 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnDecompressorAvailable() { 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LE(QUIC_VERSION_12, version()); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(headers_id_, 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->decompressor()->current_header_id()); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!headers_decompressed_); 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!decompression_failed_); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, decompressed_headers_.length()); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (!headers_decompressed_) { 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct iovec iovec; 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sequencer()->GetReadableRegions(&iovec, 1) == 0) { 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t bytes_consumed = session()->decompressor()->DecompressData( 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringPiece(static_cast<char*>(iovec.iov_base), 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iovec.iov_len), 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LE(bytes_consumed, iovec.iov_len); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (decompression_failed_) { 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->MarkConsumed(bytes_consumed); 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_decompressed_ = 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->decompressor()->current_header_id() != headers_id_; 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Either the headers are complete, or the all data as been consumed. 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessHeaderData(); // Unprocessed headers remain in decompressed_headers_. 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsDoneReading()) { 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFinRead(); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (FinishedReadingHeaders()) { 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->FlushBufferedFrames(); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDataStream::OnDecompressedData(StringPiece data) { 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_GE(QUIC_VERSION_12, version()); 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data.AppendToString(&decompressed_headers_); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnDecompressionError() { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LE(QUIC_VERSION_12, version()); 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!decompression_failed_); 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decompression_failed_ = true; 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnStreamHeaders(StringPiece headers_data) { 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LT(QUIC_VERSION_12, version()); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_data.AppendToString(&decompressed_headers_); 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessHeaderData(); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnStreamHeadersPriority(QuicPriority priority) { 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(session()->connection()->is_server()); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) set_priority(priority); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnStreamHeadersComplete(bool fin, size_t frame_len) { 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_LT(QUIC_VERSION_12, version()); 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_decompressed_ = true; 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin) { 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->OnStreamFrame(QuicStreamFrame(id(), fin, 0, IOVector())); 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProcessHeaderData(); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (FinishedReadingHeaders()) { 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sequencer()->FlushBufferedFrames(); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicDataStream::OnClose() { 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReliableQuicStream::OnClose(); 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (visitor_) { 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Visitor* visitor = visitor_; 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calling Visitor::OnClose() may result the destruction of the visitor, 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so we need to ensure we don't call it again. 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor_ = NULL; 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) visitor->OnClose(this); 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 QuicDataStream::StripPriorityAndHeaderId( 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* data, uint32 data_len) { 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 total_bytes_parsed = 0; 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!priority_parsed_ && session()->connection()->is_server()) { 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicPriority temporary_priority = priority_; 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_parsed = StripUint32( 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data, data_len, &headers_id_and_priority_buffer_, &temporary_priority); 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (total_bytes_parsed > 0 && headers_id_and_priority_buffer_.size() == 0) { 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_parsed_ = true; 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Spdy priorities are inverted, so the highest numerical value is the 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // lowest legal priority. 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (temporary_priority > QuicUtils::LowestPriority()) { 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->connection()->SendConnectionClose(QUIC_INVALID_PRIORITY); 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) priority_ = temporary_priority; 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data += total_bytes_parsed; 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data_len -= total_bytes_parsed; 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (data_len > 0 && headers_id_ == 0u) { 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The headers ID has not yet been read. Strip it from the beginning of 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the data stream. 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_bytes_parsed += StripUint32( 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) data, data_len, &headers_id_and_priority_buffer_, &headers_id_); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return total_bytes_parsed; 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicDataStream::FinishedReadingHeaders() { 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (headers_id_ != 0 || version() > QUIC_VERSION_12) && 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) headers_decompressed_ && decompressed_headers_.empty(); 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace net 393