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