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 |