| 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 |