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