xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_body_manager.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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