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 QUIC_EXPORT_PRIVATE 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 HasBytesToRead()69 bool HasBytesToRead() const { return !fragments_.empty(); } 70 total_body_bytes_received()71 uint64_t total_body_bytes_received() const { 72 return total_body_bytes_received_; 73 } 74 75 private: 76 // A Fragment instance represents a body fragment with a count of bytes 77 // received afterwards but before the next body fragment that can be marked 78 // consumed as soon as all of the body fragment is read. 79 struct QUIC_EXPORT_PRIVATE Fragment { 80 // |body| must not be empty. 81 absl::string_view body; 82 // Might be zero. 83 QuicByteCount trailing_non_body_byte_count; 84 }; 85 // Queue of body fragments and trailing non-body byte counts. 86 quiche::QuicheCircularDeque<Fragment> fragments_; 87 // Total body bytes received. 88 QuicByteCount total_body_bytes_received_; 89 }; 90 91 } // namespace quic 92 93 #endif // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_ 94