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_headers_stream.h" | 5 #include "net/quic/core/quic_headers_stream.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 // HTTP/2 DATA frame headers are inserted on the way down to the | 62 // HTTP/2 DATA frame headers are inserted on the way down to the |
63 // session layer. |ForceAckListener| filters the |OnPacketAcked()| | 63 // session layer. |ForceAckListener| filters the |OnPacketAcked()| |
64 // notifications generated by the session layer to not count the extra | 64 // notifications generated by the session layer to not count the extra |
65 // bytes. Otherwise, code that is using ack listener on streams might | 65 // bytes. Otherwise, code that is using ack listener on streams might |
66 // consider it an error if more bytes are acked than were written to | 66 // consider it an error if more bytes are acked than were written to |
67 // the stream, it is the case with some internal stats gathering code. | 67 // the stream, it is the case with some internal stats gathering code. |
68 class ForceHolAckListener : public QuicAckListenerInterface { | 68 class ForceHolAckListener : public QuicAckListenerInterface { |
69 public: | 69 public: |
70 // |extra_bytes| should be initialized to the size of the HTTP/2 | 70 // |extra_bytes| should be initialized to the size of the HTTP/2 |
71 // DATA frame header inserted when forced HOL blocking is enabled. | 71 // DATA frame header inserted when forced HOL blocking is enabled. |
72 ForceHolAckListener(QuicAckListenerInterface* stream_ack_listener, | 72 ForceHolAckListener( |
73 int extra_bytes) | 73 scoped_refptr<QuicAckListenerInterface> stream_ack_listener, |
74 : stream_ack_listener_(stream_ack_listener), extra_bytes_(extra_bytes) { | 74 int extra_bytes) |
| 75 : stream_ack_listener_(std::move(stream_ack_listener)), |
| 76 extra_bytes_(extra_bytes) { |
75 DCHECK_GE(extra_bytes, 0); | 77 DCHECK_GE(extra_bytes, 0); |
76 } | 78 } |
77 | 79 |
78 void OnPacketAcked(int acked_bytes, QuicTime::Delta ack_delay_time) override { | 80 void OnPacketAcked(int acked_bytes, QuicTime::Delta ack_delay_time) override { |
79 if (extra_bytes_ > 0) { | 81 if (extra_bytes_ > 0) { |
80 // Don't count the added HTTP/2 DATA frame header bytes | 82 // Don't count the added HTTP/2 DATA frame header bytes |
81 int delta = std::min(extra_bytes_, acked_bytes); | 83 int delta = std::min(extra_bytes_, acked_bytes); |
82 extra_bytes_ -= delta; | 84 extra_bytes_ -= delta; |
83 acked_bytes -= delta; | 85 acked_bytes -= delta; |
84 } | 86 } |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 spdy_framer_(SpdyFramer::ENABLE_COMPRESSION), | 332 spdy_framer_(SpdyFramer::ENABLE_COMPRESSION), |
331 spdy_framer_visitor_(new SpdyFramerVisitor(this)) { | 333 spdy_framer_visitor_(new SpdyFramerVisitor(this)) { |
332 spdy_framer_.set_visitor(spdy_framer_visitor_.get()); | 334 spdy_framer_.set_visitor(spdy_framer_visitor_.get()); |
333 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); | 335 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); |
334 // The headers stream is exempt from connection level flow control. | 336 // The headers stream is exempt from connection level flow control. |
335 DisableConnectionFlowControlForThisStream(); | 337 DisableConnectionFlowControlForThisStream(); |
336 } | 338 } |
337 | 339 |
338 QuicHeadersStream::~QuicHeadersStream() {} | 340 QuicHeadersStream::~QuicHeadersStream() {} |
339 | 341 |
340 size_t QuicHeadersStream::WriteHeaders(QuicStreamId stream_id, | 342 size_t QuicHeadersStream::WriteHeaders( |
341 SpdyHeaderBlock headers, | 343 QuicStreamId stream_id, |
342 bool fin, | 344 SpdyHeaderBlock headers, |
343 SpdyPriority priority, | 345 bool fin, |
344 QuicAckListenerInterface* ack_listener) { | 346 SpdyPriority priority, |
| 347 const scoped_refptr<QuicAckListenerInterface>& ack_listener) { |
345 SpdyHeadersIR headers_frame(stream_id, std::move(headers)); | 348 SpdyHeadersIR headers_frame(stream_id, std::move(headers)); |
346 headers_frame.set_fin(fin); | 349 headers_frame.set_fin(fin); |
347 if (session()->perspective() == Perspective::IS_CLIENT) { | 350 if (session()->perspective() == Perspective::IS_CLIENT) { |
348 headers_frame.set_has_priority(true); | 351 headers_frame.set_has_priority(true); |
349 headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority)); | 352 headers_frame.set_weight(Spdy3PriorityToHttp2Weight(priority)); |
350 } | 353 } |
351 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); | 354 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame)); |
352 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, | 355 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, |
353 ack_listener); | 356 ack_listener); |
354 return frame.size(); | 357 return frame.size(); |
(...skipping 16 matching lines...) Expand all Loading... |
371 | 374 |
372 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); | 375 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); |
373 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr); | 376 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, nullptr); |
374 return frame.size(); | 377 return frame.size(); |
375 } | 378 } |
376 | 379 |
377 void QuicHeadersStream::WriteDataFrame( | 380 void QuicHeadersStream::WriteDataFrame( |
378 QuicStreamId id, | 381 QuicStreamId id, |
379 StringPiece data, | 382 StringPiece data, |
380 bool fin, | 383 bool fin, |
381 QuicAckListenerInterface* ack_notifier_delegate) { | 384 const scoped_refptr<QuicAckListenerInterface>& ack_notifier_delegate) { |
382 SpdyDataIR spdy_data(id, data); | 385 SpdyDataIR spdy_data(id, data); |
383 spdy_data.set_fin(fin); | 386 spdy_data.set_fin(fin); |
384 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); | 387 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data)); |
385 scoped_refptr<ForceHolAckListener> ack_listener; | 388 scoped_refptr<ForceHolAckListener> ack_listener; |
386 if (ack_notifier_delegate != nullptr) { | 389 if (ack_notifier_delegate != nullptr) { |
387 ack_listener = new ForceHolAckListener(ack_notifier_delegate, | 390 ack_listener = new ForceHolAckListener(ack_notifier_delegate, |
388 frame.size() - data.length()); | 391 frame.size() - data.length()); |
389 } | 392 } |
390 // Use buffered writes so that coherence of framing is preserved | 393 // Use buffered writes so that coherence of framing is preserved |
391 // between streams. | 394 // between streams. |
392 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, | 395 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, |
393 ack_listener.get()); | 396 ack_listener); |
394 } | 397 } |
395 | 398 |
396 QuicConsumedData QuicHeadersStream::WritevStreamData( | 399 QuicConsumedData QuicHeadersStream::WritevStreamData( |
397 QuicStreamId id, | 400 QuicStreamId id, |
398 QuicIOVector iov, | 401 QuicIOVector iov, |
399 QuicStreamOffset offset, | 402 QuicStreamOffset offset, |
400 bool fin, | 403 bool fin, |
401 QuicAckListenerInterface* ack_notifier_delegate) { | 404 const scoped_refptr<QuicAckListenerInterface>& ack_notifier_delegate) { |
402 const size_t max_len = | 405 const size_t max_len = |
403 kSpdyInitialFrameSizeLimit - SpdyConstants::kDataFrameMinimumSize; | 406 kSpdyInitialFrameSizeLimit - SpdyConstants::kDataFrameMinimumSize; |
404 | 407 |
405 QuicConsumedData result(0, false); | 408 QuicConsumedData result(0, false); |
406 size_t total_length = iov.total_length; | 409 size_t total_length = iov.total_length; |
407 | 410 |
408 if (total_length == 0 && fin) { | 411 if (total_length == 0 && fin) { |
409 WriteDataFrame(id, StringPiece(), true, ack_notifier_delegate); | 412 WriteDataFrame(id, StringPiece(), true, ack_notifier_delegate); |
410 result.fin_consumed = true; | 413 result.fin_consumed = true; |
411 return result; | 414 return result; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 return true; | 626 return true; |
624 } | 627 } |
625 frame_len_ -= len; | 628 frame_len_ -= len; |
626 // Ignore fin_ while there is more data coming, if frame_len_ > 0. | 629 // Ignore fin_ while there is more data coming, if frame_len_ > 0. |
627 spdy_session_->OnStreamFrameData(stream_id, data, len, | 630 spdy_session_->OnStreamFrameData(stream_id, data, len, |
628 frame_len_ > 0 ? false : fin_); | 631 frame_len_ > 0 ? false : fin_); |
629 return true; | 632 return true; |
630 } | 633 } |
631 | 634 |
632 } // namespace net | 635 } // namespace net |
OLD | NEW |