OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/reliable_quic_stream.h" | 5 #include "net/quic/reliable_quic_stream.h" |
6 | 6 |
7 #include "net/quic/quic_session.h" | 7 #include "net/quic/quic_session.h" |
8 #include "net/quic/quic_spdy_decompressor.h" | 8 #include "net/quic/quic_spdy_decompressor.h" |
9 #include "net/spdy/write_blocked_list.h" | 9 #include "net/spdy/write_blocked_list.h" |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 headers_decompressed_(false), | 54 headers_decompressed_(false), |
55 priority_(kDefaultPriority), | 55 priority_(kDefaultPriority), |
56 headers_id_(0), | 56 headers_id_(0), |
57 decompression_failed_(false), | 57 decompression_failed_(false), |
58 stream_error_(QUIC_STREAM_NO_ERROR), | 58 stream_error_(QUIC_STREAM_NO_ERROR), |
59 connection_error_(QUIC_NO_ERROR), | 59 connection_error_(QUIC_NO_ERROR), |
60 read_side_closed_(false), | 60 read_side_closed_(false), |
61 write_side_closed_(false), | 61 write_side_closed_(false), |
62 priority_parsed_(false), | 62 priority_parsed_(false), |
63 fin_buffered_(false), | 63 fin_buffered_(false), |
64 fin_sent_(false) { | 64 fin_sent_(false), |
| 65 is_server_(session_->is_server()) { |
65 } | 66 } |
66 | 67 |
67 ReliableQuicStream::~ReliableQuicStream() { | 68 ReliableQuicStream::~ReliableQuicStream() { |
68 } | 69 } |
69 | 70 |
70 bool ReliableQuicStream::WillAcceptStreamFrame( | 71 bool ReliableQuicStream::WillAcceptStreamFrame( |
71 const QuicStreamFrame& frame) const { | 72 const QuicStreamFrame& frame) const { |
72 if (read_side_closed_) { | 73 if (read_side_closed_) { |
73 return true; | 74 return true; |
74 } | 75 } |
75 if (frame.stream_id != id_) { | 76 if (frame.stream_id != id_) { |
76 LOG(ERROR) << "Error!"; | 77 LOG(ERROR) << "Error!"; |
77 return false; | 78 return false; |
78 } | 79 } |
79 return sequencer_.WillAcceptStreamFrame(frame); | 80 return sequencer_.WillAcceptStreamFrame(frame); |
80 } | 81 } |
81 | 82 |
82 bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { | 83 bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { |
83 DCHECK_EQ(frame.stream_id, id_); | 84 DCHECK_EQ(frame.stream_id, id_); |
84 if (read_side_closed_) { | 85 if (read_side_closed_) { |
85 DLOG(INFO) << "Ignoring frame " << frame.stream_id; | 86 DLOG(INFO) << ENDPOINT << "Ignoring frame " << frame.stream_id; |
86 // We don't want to be reading: blackhole the data. | 87 // We don't want to be reading: blackhole the data. |
87 return true; | 88 return true; |
88 } | 89 } |
89 // Note: This count include duplicate data received. | 90 // Note: This count include duplicate data received. |
90 stream_bytes_read_ += frame.data.length(); | 91 stream_bytes_read_ += frame.data.length(); |
91 | 92 |
92 bool accepted = sequencer_.OnStreamFrame(frame); | 93 bool accepted = sequencer_.OnStreamFrame(frame); |
93 | 94 |
94 return accepted; | 95 return accepted; |
95 } | 96 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 StringPiece data, bool fin) { | 255 StringPiece data, bool fin) { |
255 struct iovec iov = {const_cast<char*>(data.data()), | 256 struct iovec iov = {const_cast<char*>(data.data()), |
256 static_cast<size_t>(data.size())}; | 257 static_cast<size_t>(data.size())}; |
257 return WritevDataInternal(&iov, 1, fin); | 258 return WritevDataInternal(&iov, 1, fin); |
258 } | 259 } |
259 | 260 |
260 QuicConsumedData ReliableQuicStream::WritevDataInternal(const struct iovec* iov, | 261 QuicConsumedData ReliableQuicStream::WritevDataInternal(const struct iovec* iov, |
261 int iov_count, | 262 int iov_count, |
262 bool fin) { | 263 bool fin) { |
263 if (write_side_closed_) { | 264 if (write_side_closed_) { |
264 DLOG(ERROR) << "Attempt to write when the write side is closed"; | 265 DLOG(ERROR) << ENDPOINT << "Attempt to write when the write side is closed"; |
265 return QuicConsumedData(0, false); | 266 return QuicConsumedData(0, false); |
266 } | 267 } |
267 | 268 |
268 size_t write_length = 0u; | 269 size_t write_length = 0u; |
269 for (int i = 0; i < iov_count; ++i) { | 270 for (int i = 0; i < iov_count; ++i) { |
270 write_length += iov[i].iov_len; | 271 write_length += iov[i].iov_len; |
271 } | 272 } |
272 QuicConsumedData consumed_data = | 273 QuicConsumedData consumed_data = |
273 session()->WritevData(id(), iov, iov_count, stream_bytes_written_, fin); | 274 session()->WritevData(id(), iov, iov_count, stream_bytes_written_, fin); |
274 stream_bytes_written_ += consumed_data.bytes_consumed; | 275 stream_bytes_written_ += consumed_data.bytes_consumed; |
(...skipping 11 matching lines...) Expand all Loading... |
286 } | 287 } |
287 | 288 |
288 QuicPriority ReliableQuicStream::EffectivePriority() const { | 289 QuicPriority ReliableQuicStream::EffectivePriority() const { |
289 return priority(); | 290 return priority(); |
290 } | 291 } |
291 | 292 |
292 void ReliableQuicStream::CloseReadSide() { | 293 void ReliableQuicStream::CloseReadSide() { |
293 if (read_side_closed_) { | 294 if (read_side_closed_) { |
294 return; | 295 return; |
295 } | 296 } |
296 DLOG(INFO) << "Done reading from stream " << id(); | 297 DLOG(INFO) << ENDPOINT << "Done reading from stream " << id(); |
297 | 298 |
298 read_side_closed_ = true; | 299 read_side_closed_ = true; |
299 if (write_side_closed_) { | 300 if (write_side_closed_) { |
300 DLOG(INFO) << "Closing stream: " << id(); | 301 DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); |
301 session_->CloseStream(id()); | 302 session_->CloseStream(id()); |
302 } | 303 } |
303 } | 304 } |
304 | 305 |
305 uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { | 306 uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { |
306 DCHECK_NE(0u, data_len); | 307 DCHECK_NE(0u, data_len); |
307 if (id() == kCryptoStreamId) { | 308 if (id() == kCryptoStreamId) { |
308 // The crypto stream does not use compression. | 309 // The crypto stream does not use compression. |
309 return ProcessData(data, data_len); | 310 return ProcessData(data, data_len); |
310 } | 311 } |
(...skipping 20 matching lines...) Expand all Loading... |
331 total_bytes_consumed += ProcessData(data, data_len); | 332 total_bytes_consumed += ProcessData(data, data_len); |
332 } | 333 } |
333 return total_bytes_consumed; | 334 return total_bytes_consumed; |
334 } | 335 } |
335 | 336 |
336 QuicHeaderId current_header_id = | 337 QuicHeaderId current_header_id = |
337 session_->decompressor()->current_header_id(); | 338 session_->decompressor()->current_header_id(); |
338 // Ensure that this header id looks sane. | 339 // Ensure that this header id looks sane. |
339 if (headers_id_ < current_header_id || | 340 if (headers_id_ < current_header_id || |
340 headers_id_ > kMaxHeaderIdDelta + current_header_id) { | 341 headers_id_ > kMaxHeaderIdDelta + current_header_id) { |
341 DVLOG(1) << "Invalid headers for stream: " << id() | 342 DVLOG(1) << ENDPOINT |
| 343 << "Invalid headers for stream: " << id() |
342 << " header_id: " << headers_id_ | 344 << " header_id: " << headers_id_ |
343 << " current_header_id: " << current_header_id; | 345 << " current_header_id: " << current_header_id; |
344 session_->connection()->SendConnectionClose(QUIC_INVALID_HEADER_ID); | 346 session_->connection()->SendConnectionClose(QUIC_INVALID_HEADER_ID); |
345 return total_bytes_consumed; | 347 return total_bytes_consumed; |
346 } | 348 } |
347 | 349 |
348 // If we are head-of-line blocked on decompression, then back up. | 350 // If we are head-of-line blocked on decompression, then back up. |
349 if (current_header_id != headers_id_) { | 351 if (current_header_id != headers_id_) { |
350 session_->MarkDecompressionBlocked(headers_id_, id()); | 352 session_->MarkDecompressionBlocked(headers_id_, id()); |
351 DVLOG(1) << "Unable to decompress header data for stream: " << id() | 353 DVLOG(1) << ENDPOINT |
| 354 << "Unable to decompress header data for stream: " << id() |
352 << " header_id: " << headers_id_; | 355 << " header_id: " << headers_id_; |
353 return total_bytes_consumed; | 356 return total_bytes_consumed; |
354 } | 357 } |
355 | 358 |
356 // Decompressed data will be delivered to decompressed_headers_. | 359 // Decompressed data will be delivered to decompressed_headers_. |
357 size_t bytes_consumed = session_->decompressor()->DecompressData( | 360 size_t bytes_consumed = session_->decompressor()->DecompressData( |
358 StringPiece(data, data_len), this); | 361 StringPiece(data, data_len), this); |
359 DCHECK_NE(0u, bytes_consumed); | 362 DCHECK_NE(0u, bytes_consumed); |
360 if (bytes_consumed > data_len) { | 363 if (bytes_consumed > data_len) { |
361 DCHECK(false) << "DecompressData returned illegal value"; | 364 DCHECK(false) << "DecompressData returned illegal value"; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 DCHECK(!decompression_failed_); | 459 DCHECK(!decompression_failed_); |
457 decompression_failed_ = true; | 460 decompression_failed_ = true; |
458 session_->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE); | 461 session_->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE); |
459 } | 462 } |
460 | 463 |
461 | 464 |
462 void ReliableQuicStream::CloseWriteSide() { | 465 void ReliableQuicStream::CloseWriteSide() { |
463 if (write_side_closed_) { | 466 if (write_side_closed_) { |
464 return; | 467 return; |
465 } | 468 } |
466 DLOG(INFO) << "Done writing to stream " << id(); | 469 DLOG(INFO) << ENDPOINT << "Done writing to stream " << id(); |
467 | 470 |
468 write_side_closed_ = true; | 471 write_side_closed_ = true; |
469 if (read_side_closed_) { | 472 if (read_side_closed_) { |
470 DLOG(INFO) << "Closing stream: " << id(); | 473 DLOG(INFO) << ENDPOINT << "Closing stream: " << id(); |
471 session_->CloseStream(id()); | 474 session_->CloseStream(id()); |
472 } | 475 } |
473 } | 476 } |
474 | 477 |
475 bool ReliableQuicStream::HasBufferedData() { | 478 bool ReliableQuicStream::HasBufferedData() { |
476 return !queued_data_.empty(); | 479 return !queued_data_.empty(); |
477 } | 480 } |
478 | 481 |
479 void ReliableQuicStream::OnClose() { | 482 void ReliableQuicStream::OnClose() { |
480 CloseReadSide(); | 483 CloseReadSide(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 if (data_len > 0 && headers_id_ == 0u) { | 516 if (data_len > 0 && headers_id_ == 0u) { |
514 // The headers ID has not yet been read. Strip it from the beginning of | 517 // The headers ID has not yet been read. Strip it from the beginning of |
515 // the data stream. | 518 // the data stream. |
516 total_bytes_parsed += StripUint32( | 519 total_bytes_parsed += StripUint32( |
517 data, data_len, &headers_id_and_priority_buffer_, &headers_id_); | 520 data, data_len, &headers_id_and_priority_buffer_, &headers_id_); |
518 } | 521 } |
519 return total_bytes_parsed; | 522 return total_bytes_parsed; |
520 } | 523 } |
521 | 524 |
522 } // namespace net | 525 } // namespace net |
OLD | NEW |