reliable_quic_stream.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/reliable_quic_stream.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_session.h"
8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/quic/quic_spdy_decompressor.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)using std::min;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace {
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// This is somewhat arbitrary.  It's possible, but unlikely, we will either fail
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// to set a priority client-side, or cancel a stream before stripping the
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// priority from the wire server-side.  In either case, start out with a
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// priority in the middle.
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)QuicPriority kDefaultPriority = 3;
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Appends bytes from data into partial_data_buffer.  Once partial_data_buffer
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// reaches 4 bytes, copies the data into 'result' and clears
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// partial_data_buffer.
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Returns the number of bytes consumed.
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)uint32 StripUint32(const char* data, uint32 data_len,
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   string* partial_data_buffer,
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   uint32* result) {
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_GT(4u, partial_data_buffer->length());
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  size_t missing_size = 4 - partial_data_buffer->length();
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (data_len < missing_size) {
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    StringPiece(data, data_len).AppendToString(partial_data_buffer);
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return data_len;
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  StringPiece(data, missing_size).AppendToString(partial_data_buffer);
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(4u, partial_data_buffer->length());
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  memcpy(result, partial_data_buffer->data(), 4);
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  partial_data_buffer->clear();
40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return missing_size;
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::ReliableQuicStream(QuicStreamId id,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       QuicSession* session)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : sequencer_(this),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_(id),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session_(session),
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      visitor_(NULL),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stream_bytes_read_(0),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stream_bytes_written_(0),
53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      headers_decompressed_(false),
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      priority_(kDefaultPriority),
55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      headers_id_(0),
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      decompression_failed_(false),
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      stream_error_(QUIC_STREAM_NO_ERROR),
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      connection_error_(QUIC_NO_ERROR),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_side_closed_(false),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      write_side_closed_(false),
61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      priority_parsed_(false),
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin_buffered_(false),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin_sent_(false) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::WillAcceptStreamFrame(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const QuicStreamFrame& frame) const {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_side_closed_) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (frame.stream_id != id_) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Error!";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sequencer_.WillAcceptStreamFrame(frame);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(frame.stream_id, id_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_side_closed_) {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(INFO) << "Ignoring frame " << frame.stream_id;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We don't want to be reading: blackhole the data.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Note: This count include duplicate data received.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_bytes_read_ += frame.data.length();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool accepted = sequencer_.OnStreamFrame(frame);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return accepted;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ReliableQuicStream::OnStreamReset(QuicRstStreamErrorCode error) {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_error_ = error;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TerminateFromPeer(false);  // Full close.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::ConnectionClose(QuicErrorCode error, bool from_peer) {
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (read_side_closed_ && write_side_closed_) {
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (error != QUIC_NO_ERROR) {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    stream_error_ = QUIC_STREAM_CONNECTION_ERROR;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    connection_error_ = error;
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (from_peer) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TerminateFromPeer(false);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseWriteSide();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseReadSide();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::TerminateFromPeer(bool half_close) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!half_close) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseWriteSide();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloseReadSide();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ReliableQuicStream::Close(QuicRstStreamErrorCode error) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stream_error_ = error;
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error != QUIC_STREAM_NO_ERROR)  {
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Sending a RstStream results in calling CloseStream.
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    session()->SendRstStream(id(), error);
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    session_->CloseStream(id());
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)size_t ReliableQuicStream::Readv(const struct iovec* iov, size_t iov_len) {
136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (headers_decompressed_ && decompressed_headers_.empty()) {
137b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return sequencer_.Readv(iov, iov_len);
138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
139b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t bytes_consumed = 0;
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  size_t iov_index = 0;
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  while (iov_index < iov_len &&
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)         decompressed_headers_.length() > bytes_consumed) {
1435e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    size_t bytes_to_read = min(iov[iov_index].iov_len,
1445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)                               decompressed_headers_.length() - bytes_consumed);
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base);
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    memcpy(iov_ptr,
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)           decompressed_headers_.data() + bytes_consumed, bytes_to_read);
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    bytes_consumed += bytes_to_read;
149b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    ++iov_index;
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  decompressed_headers_.erase(0, bytes_consumed);
152b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return bytes_consumed;
153b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int ReliableQuicStream::GetReadableRegions(iovec* iov, size_t iov_len) {
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (headers_decompressed_ && decompressed_headers_.empty()) {
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return sequencer_.GetReadableRegions(iov, iov_len);
158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (iov_len == 0) {
160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return 0;
161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  iov[0].iov_base = static_cast<void*>(
163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      const_cast<char*>(decompressed_headers_.data()));
164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  iov[0].iov_len = decompressed_headers_.length();
165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return 1;
166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::IsHalfClosed() const {
169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!headers_decompressed_ || !decompressed_headers_.empty()) {
170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return false;
171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sequencer_.IsHalfClosed();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::HasBytesToRead() const {
176b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return !decompressed_headers_.empty() || sequencer_.HasBytesToRead();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const IPEndPoint& ReliableQuicStream::GetPeerAddress() const {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return session_->peer_address();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)QuicSpdyCompressor* ReliableQuicStream::compressor() {
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return session_->compressor();
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool ReliableQuicStream::GetSSLInfo(SSLInfo* ssl_info) {
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return session_->GetSSLInfo(ssl_info);
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteData(StringPiece data, bool fin) {
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(data.size() > 0 || fin);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return WriteOrBuffer(data, fin);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteOrBuffer(StringPiece data, bool fin) {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!fin_buffered_);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed_data(0, false);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fin_buffered_ = fin;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (queued_data_.empty()) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    consumed_data = WriteDataInternal(string(data.data(), data.length()), fin);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_LE(consumed_data.bytes_consumed, data.length());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there's unconsumed data or an unconsumed fin, queue it.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (consumed_data.bytes_consumed < data.length() ||
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (fin && !consumed_data.fin_consumed)) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    queued_data_.push_back(
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        string(data.data() + consumed_data.bytes_consumed,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               data.length() - consumed_data.bytes_consumed));
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return QuicConsumedData(data.size(), true);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnCanWrite() {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool fin = false;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (!queued_data_.empty()) {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string& data = queued_data_.front();
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (queued_data_.size() == 1 && fin_buffered_) {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin = true;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicConsumedData consumed_data = WriteDataInternal(data, fin);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (consumed_data.bytes_consumed == data.size() &&
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fin == consumed_data.fin_consumed) {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_data_.pop_front();
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      queued_data_.front().erase(0, consumed_data.bytes_consumed);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteDataInternal(
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StringPiece data, bool fin) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_side_closed_) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Attempt to write when the write side is closed";
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return QuicConsumedData(0, false);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed_data =
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session()->WriteData(id(), data, stream_bytes_written_, fin);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  stream_bytes_written_ += consumed_data.bytes_consumed;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (consumed_data.bytes_consumed == data.length()) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (fin && consumed_data.fin_consumed) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fin_sent_ = true;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CloseWriteSide();
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else if (fin && !consumed_data.fin_consumed) {
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      session_->MarkWriteBlocked(id());
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    session_->MarkWriteBlocked(id());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return consumed_data;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() {
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (read_side_closed_) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DLOG(INFO) << "Done reading from stream " << id();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_side_closed_ = true;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_side_closed_) {
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(INFO) << "Closing stream: " << id();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->CloseStream(id());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) {
273b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (id() == kCryptoStreamId) {
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (data_len == 0) {
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return 0;
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
277b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // The crypto stream does not use compression.
278b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return ProcessData(data, data_len);
279b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
281b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  uint32 total_bytes_consumed = 0;
282b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (headers_id_ == 0u) {
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    total_bytes_consumed += StripPriorityAndHeaderId(data, data_len);
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    data += total_bytes_consumed;
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    data_len -= total_bytes_consumed;
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (data_len == 0) {
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return total_bytes_consumed;
288b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
289b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
290b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK_NE(0u, headers_id_);
291b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
292b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Once the headers are finished, we simply pass the data through.
293b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (headers_decompressed_) {
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    // Some buffered header data remains.
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (!decompressed_headers_.empty()) {
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      ProcessHeaderData();
297b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (decompressed_headers_.empty()) {
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      DVLOG(1) << "Delegating procesing to ProcessData";
300b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      total_bytes_consumed += ProcessData(data, data_len);
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return total_bytes_consumed;
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
305b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  QuicHeaderId current_header_id =
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      session_->decompressor()->current_header_id();
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Ensure that this header id looks sane.
308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (headers_id_ < current_header_id ||
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      headers_id_ > kMaxHeaderIdDelta + current_header_id) {
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DVLOG(1) << "Invalid headers for stream: " << id()
311b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)             << " header_id: " << headers_id_
312b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)             << " current_header_id: " << current_header_id;
313b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    session_->connection()->SendConnectionClose(QUIC_INVALID_HEADER_ID);
314b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return total_bytes_consumed;
315b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
316b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
317b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // If we are head-of-line blocked on decompression, then back up.
318b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (current_header_id != headers_id_) {
319b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    session_->MarkDecompressionBlocked(headers_id_, id());
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DVLOG(1) << "Unable to decompress header data for stream: " << id()
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             << " header_id: " << headers_id_;
322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return total_bytes_consumed;
323b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
324b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Decompressed data will be delivered to decompressed_headers_.
326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t bytes_consumed = session_->decompressor()->DecompressData(
327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      StringPiece(data, data_len), this);
328558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK_NE(0u, bytes_consumed);
329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (bytes_consumed > data_len) {
330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    DCHECK(false) << "DecompressData returned illegal value";
331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    OnDecompressionError();
332558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return total_bytes_consumed;
333558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  total_bytes_consumed += bytes_consumed;
335558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  data += bytes_consumed;
336558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  data_len -= bytes_consumed;
337558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
338558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (decompression_failed_) {
339558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // The session will have been closed in OnDecompressionError.
340558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return total_bytes_consumed;
341558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
342b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
343b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Headers are complete if the decompressor has moved on to the
344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // next stream.
345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  headers_decompressed_ =
346b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      session_->decompressor()->current_header_id() != headers_id_;
347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!headers_decompressed_) {
348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    DCHECK_EQ(0u, data_len);
349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
350b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
351b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProcessHeaderData();
352b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
353558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!headers_decompressed_ || !decompressed_headers_.empty()) {
354558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return total_bytes_consumed;
355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
357b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // We have processed all of the decompressed data but we might
358b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // have some more raw data to process.
359558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (data_len > 0) {
360558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    total_bytes_consumed += ProcessData(data, data_len);
361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
363b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // The sequencer will push any additional buffered frames if this data
364b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // has been completely consumed.
365b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return total_bytes_consumed;
366b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
368b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)uint32 ReliableQuicStream::ProcessHeaderData() {
369b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (decompressed_headers_.empty()) {
370b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return 0;
371b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
372b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
373b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  size_t bytes_processed = ProcessData(decompressed_headers_.data(),
374b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                       decompressed_headers_.length());
375b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (bytes_processed == decompressed_headers_.length()) {
376b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    decompressed_headers_.clear();
377b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  } else {
378b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    decompressed_headers_ = decompressed_headers_.erase(0, bytes_processed);
379b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
380b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return bytes_processed;
381b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void ReliableQuicStream::OnDecompressorAvailable() {
384b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK_EQ(headers_id_,
385b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            session_->decompressor()->current_header_id());
386b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK(!headers_decompressed_);
387558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!decompression_failed_);
388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  DCHECK_EQ(0u, decompressed_headers_.length());
389b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
390b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  while (!headers_decompressed_) {
391558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    struct iovec iovec;
392558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (sequencer_.GetReadableRegions(&iovec, 1) == 0) {
393b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return;
394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
395b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
396558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    size_t bytes_consumed = session_->decompressor()->DecompressData(
397558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        StringPiece(static_cast<char*>(iovec.iov_base),
398558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    iovec.iov_len),
399558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        this);
400558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    DCHECK_LE(bytes_consumed, iovec.iov_len);
401558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (decompression_failed_) {
402558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      return;
403b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
404558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    sequencer_.MarkConsumed(bytes_consumed);
405558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    headers_decompressed_ =
407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        session_->decompressor()->current_header_id() != headers_id_;
408b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
409b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
410b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Either the headers are complete, or the all data as been consumed.
411b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ProcessHeaderData();  // Unprocessed headers remain in decompressed_headers_.
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (IsHalfClosed()) {
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    TerminateFromPeer(true);
4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else if (headers_decompressed_ && decompressed_headers_.empty()) {
415b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    sequencer_.FlushBufferedFrames();
416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool ReliableQuicStream::OnDecompressedData(StringPiece data) {
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  data.AppendToString(&decompressed_headers_);
421b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  return true;
422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void ReliableQuicStream::OnDecompressionError() {
425558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!decompression_failed_);
426558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  decompression_failed_ = true;
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  session_->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE);
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (write_side_closed_) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DLOG(INFO) << "Done writing to stream " << id();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_side_closed_ = true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (read_side_closed_) {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(INFO) << "Closing stream: " << id();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    session_->CloseStream(id());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnClose() {
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CloseReadSide();
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CloseWriteSide();
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (visitor_) {
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Visitor* visitor = visitor_;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Calling Visitor::OnClose() may result the destruction of the visitor,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // so we need to ensure we don't call it again.
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor_ = NULL;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    visitor->OnClose(this);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)uint32 ReliableQuicStream::StripPriorityAndHeaderId(
458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const char* data, uint32 data_len) {
459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  uint32 total_bytes_parsed = 0;
460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!priority_parsed_ &&
462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      session_->connection()->version() >= QUIC_VERSION_9 &&
463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      session_->connection()->is_server()) {
464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    total_bytes_parsed = StripUint32(
465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data, data_len, &headers_id_and_priority_buffer_, &priority_);
466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (total_bytes_parsed > 0 && headers_id_and_priority_buffer_.size() == 0) {
467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // TODO(alyssar) check for priority out of bounds.
468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      priority_parsed_ = true;
469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    data += total_bytes_parsed;
471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    data_len -= total_bytes_parsed;
472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (data_len > 0 && headers_id_ == 0u) {
474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // The headers ID has not yet been read.  Strip it from the beginning of
475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // the data stream.
476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    total_bytes_parsed += StripUint32(
477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        data, data_len, &headers_id_and_priority_buffer_, &headers_id_);
478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return total_bytes_parsed;
480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
483