1 // Copyright (c) 2018 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 #ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ 6 #define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ 7 8 #include "absl/base/attributes.h" 9 #include "absl/strings/string_view.h" 10 #include "quiche/quic/core/quic_constants.h" 11 #include "quiche/quic/platform/api/quic_bug_tracker.h" 12 #include "quiche/quic/platform/api/quic_export.h" 13 #include "quiche/common/platform/api/quiche_iovec.h" 14 #include "quiche/common/quiche_circular_deque.h" 15 16 namespace quic { 17 18 // All data that a request stream receives falls into one of two categories: 19 // * "body", that is, DATA frame payload, which the QuicStreamSequencer must 20 // buffer until it is read; 21 // * everything else, which QuicSpdyStream immediately processes and thus could 22 // be marked as consumed with QuicStreamSequencer, unless there is some piece 23 // of body received prior that still needs to be buffered. 24 // QuicSpdyStreamBodyManager does two things: it keeps references to body 25 // fragments (owned by QuicStreamSequencer) and offers methods to read them; and 26 // it calculates the total number of bytes (including non-body bytes) the caller 27 // needs to mark consumed (with QuicStreamSequencer) when non-body bytes are 28 // received or when body is consumed. 29 class QUICHE_EXPORT QuicSpdyStreamBodyManager { 30 public: 31 QuicSpdyStreamBodyManager(); 32 ~QuicSpdyStreamBodyManager() = default; 33 34 // One of the following two methods must be called every time data is received 35 // on the request stream. 36 37 // Called when data that could immediately be marked consumed with the 38 // sequencer (provided that all previous body fragments are consumed) is 39 // received. |length| must be positive. Returns number of bytes the caller 40 // must mark consumed, which might be zero. 41 ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length); 42 43 // Called when body is received. |body| is added to |fragments_|. The data 44 // pointed to by |body| must be kept alive until an OnBodyConsumed() or 45 // ReadBody() call consumes it. |body| must not be empty. 46 void OnBody(absl::string_view body); 47 48 // Internally marks |num_bytes| of body consumed. |num_bytes| might be zero. 49 // Returns the number of bytes that the caller should mark consumed with the 50 // sequencer, which is the sum of |num_bytes| for body, and the number of any 51 // interleaving or immediately trailing non-body bytes. 52 ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes); 53 54 // Set up to |iov_len| elements of iov[] to point to available bodies: each 55 // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be 56 // set to its length. No data is copied, no data is consumed. Returns the 57 // number of iov set. 58 int PeekBody(iovec* iov, size_t iov_len) const; 59 60 // Copies data from available bodies into at most |iov_len| elements of iov[]. 61 // Internally consumes copied body bytes as well as all interleaving and 62 // immediately trailing non-body bytes. |iov.iov_base| and |iov.iov_len| are 63 // preassigned and will not be changed. Returns the total number of bytes the 64 // caller shall mark consumed. Sets |*total_bytes_read| to the total number 65 // of body bytes read. 66 ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov, size_t iov_len, 67 size_t* total_bytes_read); 68 69 // Returns true if there are any body bytes buffered that are not consumed 70 // yet. HasBytesToRead()71 bool HasBytesToRead() const { return !fragments_.empty(); } 72 73 size_t ReadableBytes() const; 74 75 // Releases all references to buffered body. Since body is buffered by 76 // QuicStreamSequencer, this method should be called when QuicStreamSequencer 77 // frees up its buffers without reading. 78 // After calling this method, HasBytesToRead() will return false, and 79 // PeekBody() and ReadBody() will read zero bytes. 80 // Does not reset `total_body_bytes_received_`. Clear()81 void Clear() { fragments_.clear(); } 82 total_body_bytes_received()83 uint64_t total_body_bytes_received() const { 84 return total_body_bytes_received_; 85 } 86 87 private: 88 // A Fragment instance represents a body fragment with a count of bytes 89 // received afterwards but before the next body fragment that can be marked 90 // consumed as soon as all of the body fragment is read. 91 struct QUICHE_EXPORT Fragment { 92 // |body| must not be empty. 93 absl::string_view body; 94 // Might be zero. 95 QuicByteCount trailing_non_body_byte_count; 96 }; 97 // Queue of body fragments and trailing non-body byte counts. 98 quiche::QuicheCircularDeque<Fragment> fragments_; 99 // Total body bytes received. 100 QuicByteCount total_body_bytes_received_; 101 }; 102 103 } // namespace quic 104 105 #endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ 106