OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/quic/reliable_quic_stream.h" |
| 6 |
| 7 #include "net/quic/quic_session.h" |
| 8 |
| 9 using base::StringPiece; |
| 10 |
| 11 namespace net { |
| 12 |
| 13 ReliableQuicStream::ReliableQuicStream(QuicStreamId id, |
| 14 QuicSession* session) |
| 15 : sequencer_(this), |
| 16 id_(id), |
| 17 offset_(0), |
| 18 session_(session), |
| 19 error_(QUIC_NO_ERROR), |
| 20 read_side_closed_(false), |
| 21 write_side_closed_(false) { |
| 22 } |
| 23 |
| 24 ReliableQuicStream::~ReliableQuicStream() { |
| 25 } |
| 26 |
| 27 bool ReliableQuicStream::WillAcceptStreamFrame( |
| 28 const QuicStreamFrame& frame) const { |
| 29 if (read_side_closed_) { |
| 30 return false; |
| 31 } |
| 32 if (frame.stream_id != id_) { |
| 33 LOG(ERROR) << "Error!"; |
| 34 return false; |
| 35 } |
| 36 return sequencer_.WillAcceptStreamFrame(frame); |
| 37 } |
| 38 |
| 39 bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { |
| 40 DCHECK_EQ(frame.stream_id, id_); |
| 41 if (read_side_closed_) { |
| 42 // This can only happen if a client sends data after sending a fin or stream |
| 43 // reset. |
| 44 Close(QUIC_STREAM_DATA_AFTER_TERMINATION); |
| 45 return false; |
| 46 } |
| 47 |
| 48 bool accepted = sequencer_.OnStreamFrame(frame); |
| 49 |
| 50 if (frame.fin) { |
| 51 sequencer_.CloseStreamAtOffset(frame.offset + frame.data.size(), |
| 52 true); |
| 53 } |
| 54 |
| 55 return accepted; |
| 56 } |
| 57 |
| 58 void ReliableQuicStream::OnStreamReset(QuicErrorCode error, |
| 59 QuicStreamOffset offset) { |
| 60 error_ = error; |
| 61 sequencer_.CloseStreamAtOffset(offset, false); // Full close |
| 62 } |
| 63 |
| 64 void ReliableQuicStream::ConnectionClose(QuicErrorCode error, bool from_peer) { |
| 65 error_ = error; |
| 66 if (from_peer) { |
| 67 TerminateFromPeer(false); |
| 68 } else { |
| 69 CloseWriteSide(); |
| 70 CloseReadSide(); |
| 71 } |
| 72 } |
| 73 |
| 74 void ReliableQuicStream::TerminateFromPeer(bool half_close) { |
| 75 if (!half_close) { |
| 76 CloseWriteSide(); |
| 77 } |
| 78 CloseReadSide(); |
| 79 } |
| 80 |
| 81 void ReliableQuicStream::Close(QuicErrorCode error) { |
| 82 error_ = error; |
| 83 session()->SendRstStream(id(), error, offset_); |
| 84 } |
| 85 |
| 86 bool ReliableQuicStream::IsHalfClosed() { |
| 87 return sequencer_.IsHalfClosed(); |
| 88 } |
| 89 |
| 90 bool ReliableQuicStream::HasBytesToRead() { |
| 91 return sequencer_.HasBytesToRead(); |
| 92 } |
| 93 |
| 94 int ReliableQuicStream::WriteData(StringPiece data, bool fin) { |
| 95 if (write_side_closed_) { |
| 96 DLOG(ERROR) << "Attempt to write when the write side is closed"; |
| 97 return 0; |
| 98 } |
| 99 |
| 100 session()->WriteData(id(), data, offset_, fin); |
| 101 offset_ += data.length(); |
| 102 if (fin) { |
| 103 CloseWriteSide(); |
| 104 } |
| 105 return data.length(); |
| 106 } |
| 107 |
| 108 void ReliableQuicStream::CloseReadSide() { |
| 109 DLOG(INFO) << "Done reading from stream " << id(); |
| 110 |
| 111 read_side_closed_ = true; |
| 112 if (write_side_closed_) { |
| 113 session_->CloseStream(id()); |
| 114 } |
| 115 } |
| 116 |
| 117 void ReliableQuicStream::CloseWriteSide() { |
| 118 DLOG(INFO) << "Done writing to stream " << id(); |
| 119 |
| 120 write_side_closed_ = true; |
| 121 if (read_side_closed_) { |
| 122 session_->CloseStream(id()); |
| 123 } |
| 124 } |
| 125 |
| 126 } // namespace net |
OLD | NEW |