| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/core/quic_spdy_stream.h" | 5 #include "net/quic/core/quic_spdy_stream.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | |
| 10 #include "net/base/parse_number.h" | 9 #include "net/base/parse_number.h" |
| 11 #include "net/quic/core/quic_spdy_session.h" | 10 #include "net/quic/core/quic_spdy_session.h" |
| 12 #include "net/quic/core/quic_utils.h" | 11 #include "net/quic/core/quic_utils.h" |
| 13 #include "net/quic/core/quic_write_blocked_list.h" | 12 #include "net/quic/core/quic_write_blocked_list.h" |
| 14 #include "net/quic/core/spdy_utils.h" | 13 #include "net/quic/core/spdy_utils.h" |
| 15 #include "net/quic/platform/api/quic_bug_tracker.h" | 14 #include "net/quic/platform/api/quic_bug_tracker.h" |
| 15 #include "net/quic/platform/api/quic_logging.h" |
| 16 #include "net/quic/platform/api/quic_text_utils.h" | 16 #include "net/quic/platform/api/quic_text_utils.h" |
| 17 | 17 |
| 18 using base::IntToString; | 18 using base::IntToString; |
| 19 using base::StringPiece; | 19 using base::StringPiece; |
| 20 using std::string; | 20 using std::string; |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 | 23 |
| 24 #define ENDPOINT \ | 24 #define ENDPOINT \ |
| 25 (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \ | 25 (session()->perspective() == Perspective::IS_SERVER ? "Server: " : "Client:" \ |
| (...skipping 19 matching lines...) Expand all Loading... |
| 45 if (spdy_session_ != nullptr) { | 45 if (spdy_session_ != nullptr) { |
| 46 spdy_session_->UnregisterStreamPriority(id()); | 46 spdy_session_->UnregisterStreamPriority(id()); |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 void QuicSpdyStream::StopReading() { | 50 void QuicSpdyStream::StopReading() { |
| 51 if (!fin_received() && !rst_received() && write_side_closed() && | 51 if (!fin_received() && !rst_received() && write_side_closed() && |
| 52 !rst_sent()) { | 52 !rst_sent()) { |
| 53 DCHECK(fin_sent()); | 53 DCHECK(fin_sent()); |
| 54 // Tell the peer to stop sending further data. | 54 // Tell the peer to stop sending further data. |
| 55 DVLOG(1) << ENDPOINT << "Send QUIC_STREAM_NO_ERROR on stream " << id(); | 55 QUIC_DVLOG(1) << ENDPOINT << "Send QUIC_STREAM_NO_ERROR on stream " << id(); |
| 56 Reset(QUIC_STREAM_NO_ERROR); | 56 Reset(QUIC_STREAM_NO_ERROR); |
| 57 } | 57 } |
| 58 QuicStream::StopReading(); | 58 QuicStream::StopReading(); |
| 59 } | 59 } |
| 60 | 60 |
| 61 size_t QuicSpdyStream::WriteHeaders( | 61 size_t QuicSpdyStream::WriteHeaders( |
| 62 SpdyHeaderBlock header_block, | 62 SpdyHeaderBlock header_block, |
| 63 bool fin, | 63 bool fin, |
| 64 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 64 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 65 size_t bytes_written = spdy_session_->WriteHeaders( | 65 size_t bytes_written = spdy_session_->WriteHeaders( |
| (...skipping 16 matching lines...) Expand all Loading... |
| 82 size_t QuicSpdyStream::WriteTrailers( | 82 size_t QuicSpdyStream::WriteTrailers( |
| 83 SpdyHeaderBlock trailer_block, | 83 SpdyHeaderBlock trailer_block, |
| 84 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 84 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 85 if (fin_sent()) { | 85 if (fin_sent()) { |
| 86 QUIC_BUG << "Trailers cannot be sent after a FIN."; | 86 QUIC_BUG << "Trailers cannot be sent after a FIN."; |
| 87 return 0; | 87 return 0; |
| 88 } | 88 } |
| 89 | 89 |
| 90 // The header block must contain the final offset for this stream, as the | 90 // The header block must contain the final offset for this stream, as the |
| 91 // trailers may be processed out of order at the peer. | 91 // trailers may be processed out of order at the peer. |
| 92 DVLOG(1) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", " | 92 QUIC_DLOG(INFO) << "Inserting trailer: (" << kFinalOffsetHeaderKey << ", " |
| 93 << stream_bytes_written() + queued_data_bytes() << ")"; | 93 << stream_bytes_written() + queued_data_bytes() << ")"; |
| 94 trailer_block.insert( | 94 trailer_block.insert( |
| 95 std::make_pair(kFinalOffsetHeaderKey, | 95 std::make_pair(kFinalOffsetHeaderKey, |
| 96 QuicTextUtils::Uint64ToString(stream_bytes_written() + | 96 QuicTextUtils::Uint64ToString(stream_bytes_written() + |
| 97 queued_data_bytes()))); | 97 queued_data_bytes()))); |
| 98 | 98 |
| 99 // Write the trailing headers with a FIN, and close stream for writing: | 99 // Write the trailing headers with a FIN, and close stream for writing: |
| 100 // trailers are the last thing to be sent on a stream. | 100 // trailers are the last thing to be sent on a stream. |
| 101 const bool kFin = true; | 101 const bool kFin = true; |
| 102 size_t bytes_written = spdy_session_->WriteHeaders( | 102 size_t bytes_written = spdy_session_->WriteHeaders( |
| 103 id(), std::move(trailer_block), kFin, priority_, std::move(ack_listener)); | 103 id(), std::move(trailer_block), kFin, priority_, std::move(ack_listener)); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 212 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 213 return; | 213 return; |
| 214 } | 214 } |
| 215 | 215 |
| 216 void QuicSpdyStream::OnTrailingHeadersComplete( | 216 void QuicSpdyStream::OnTrailingHeadersComplete( |
| 217 bool fin, | 217 bool fin, |
| 218 size_t /*frame_len*/, | 218 size_t /*frame_len*/, |
| 219 const QuicHeaderList& header_list) { | 219 const QuicHeaderList& header_list) { |
| 220 DCHECK(!trailers_decompressed_); | 220 DCHECK(!trailers_decompressed_); |
| 221 if (fin_received()) { | 221 if (fin_received()) { |
| 222 DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id(); | 222 QUIC_DLOG(ERROR) << "Received Trailers after FIN, on stream: " << id(); |
| 223 session()->connection()->CloseConnection( | 223 session()->connection()->CloseConnection( |
| 224 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin", | 224 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers after fin", |
| 225 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 225 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 226 return; | 226 return; |
| 227 } | 227 } |
| 228 if (!fin) { | 228 if (!fin) { |
| 229 DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id(); | 229 QUIC_DLOG(ERROR) << "Trailers must have FIN set, on stream: " << id(); |
| 230 session()->connection()->CloseConnection( | 230 session()->connection()->CloseConnection( |
| 231 QUIC_INVALID_HEADERS_STREAM_DATA, "Fin missing from trailers", | 231 QUIC_INVALID_HEADERS_STREAM_DATA, "Fin missing from trailers", |
| 232 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 232 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 233 return; | 233 return; |
| 234 } | 234 } |
| 235 | 235 |
| 236 size_t final_byte_offset = 0; | 236 size_t final_byte_offset = 0; |
| 237 if (!SpdyUtils::CopyAndValidateTrailers(header_list, &final_byte_offset, | 237 if (!SpdyUtils::CopyAndValidateTrailers(header_list, &final_byte_offset, |
| 238 &received_trailers_)) { | 238 &received_trailers_)) { |
| 239 DLOG(ERROR) << "Trailers are malformed: " << id(); | 239 QUIC_DLOG(ERROR) << "Trailers are malformed: " << id(); |
| 240 session()->connection()->CloseConnection( | 240 session()->connection()->CloseConnection( |
| 241 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed", | 241 QUIC_INVALID_HEADERS_STREAM_DATA, "Trailers are malformed", |
| 242 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 242 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
| 243 return; | 243 return; |
| 244 } | 244 } |
| 245 trailers_decompressed_ = true; | 245 trailers_decompressed_ = true; |
| 246 OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece())); | 246 OnStreamFrame(QuicStreamFrame(id(), fin, final_byte_offset, StringPiece())); |
| 247 } | 247 } |
| 248 | 248 |
| 249 void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) { | 249 void QuicSpdyStream::OnStreamReset(const QuicRstStreamFrame& frame) { |
| 250 if (frame.error_code != QUIC_STREAM_NO_ERROR) { | 250 if (frame.error_code != QUIC_STREAM_NO_ERROR) { |
| 251 QuicStream::OnStreamReset(frame); | 251 QuicStream::OnStreamReset(frame); |
| 252 return; | 252 return; |
| 253 } | 253 } |
| 254 DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response"; | 254 QUIC_DVLOG(1) << "Received QUIC_STREAM_NO_ERROR, not discarding response"; |
| 255 set_rst_received(true); | 255 set_rst_received(true); |
| 256 MaybeIncreaseHighestReceivedOffset(frame.byte_offset); | 256 MaybeIncreaseHighestReceivedOffset(frame.byte_offset); |
| 257 set_stream_error(frame.error_code); | 257 set_stream_error(frame.error_code); |
| 258 CloseWriteSide(); | 258 CloseWriteSide(); |
| 259 } | 259 } |
| 260 | 260 |
| 261 void QuicSpdyStream::OnClose() { | 261 void QuicSpdyStream::OnClose() { |
| 262 QuicStream::OnClose(); | 262 QuicStream::OnClose(); |
| 263 | 263 |
| 264 if (visitor_) { | 264 if (visitor_) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { | 335 QuicReferenceCountedPointer<QuicAckListenerInterface> ack_listener) { |
| 336 if (spdy_session_->headers_stream() != nullptr && | 336 if (spdy_session_->headers_stream() != nullptr && |
| 337 spdy_session_->force_hol_blocking()) { | 337 spdy_session_->force_hol_blocking()) { |
| 338 return spdy_session_->WritevStreamData(id(), iov, offset, fin, | 338 return spdy_session_->WritevStreamData(id(), iov, offset, fin, |
| 339 std::move(ack_listener)); | 339 std::move(ack_listener)); |
| 340 } | 340 } |
| 341 return QuicStream::WritevDataInner(iov, offset, fin, std::move(ack_listener)); | 341 return QuicStream::WritevDataInner(iov, offset, fin, std::move(ack_listener)); |
| 342 } | 342 } |
| 343 | 343 |
| 344 } // namespace net | 344 } // namespace net |
| OLD | NEW |