summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/http/quic_spdy_stream_body_manager.h
blob: f34801a383ce8072fc741a50117798b767cf747c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_
#define QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_

#include "absl/base/attributes.h"
#include "absl/strings/string_view.h"
#include "quic/core/quic_constants.h"
#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_export.h"
#include "quic/platform/api/quic_iovec.h"
#include "common/quiche_circular_deque.h"

namespace quic {

// All data that a request stream receives falls into one of two categories:
//  * "body", that is, DATA frame payload, which the QuicStreamSequencer must
//    buffer until it is read;
//  * everything else, which QuicSpdyStream immediately processes and thus could
//    be marked as consumed with QuicStreamSequencer, unless there is some piece
//    of body received prior that still needs to be buffered.
// QuicSpdyStreamBodyManager does two things: it keeps references to body
// fragments (owned by QuicStreamSequencer) and offers methods to read them; and
// it calculates the total number of bytes (including non-body bytes) the caller
// needs to mark consumed (with QuicStreamSequencer) when non-body bytes are
// received or when body is consumed.
class QUIC_EXPORT_PRIVATE QuicSpdyStreamBodyManager {
 public:
  QuicSpdyStreamBodyManager();
  ~QuicSpdyStreamBodyManager() = default;

  // One of the following two methods must be called every time data is received
  // on the request stream.

  // Called when data that could immediately be marked consumed with the
  // sequencer (provided that all previous body fragments are consumed) is
  // received.  |length| must be positive.  Returns number of bytes the caller
  // must mark consumed, which might be zero.
  ABSL_MUST_USE_RESULT size_t OnNonBody(QuicByteCount length);

  // Called when body is received.  |body| is added to |fragments_|.  The data
  // pointed to by |body| must be kept alive until an OnBodyConsumed() or
  // ReadBody() call consumes it.  |body| must not be empty.
  void OnBody(absl::string_view body);

  // Internally marks |num_bytes| of body consumed.  |num_bytes| might be zero.
  // Returns the number of bytes that the caller should mark consumed with the
  // sequencer, which is the sum of |num_bytes| for body, and the number of any
  // interleaving or immediately trailing non-body bytes.
  ABSL_MUST_USE_RESULT size_t OnBodyConsumed(size_t num_bytes);

  // Set up to |iov_len| elements of iov[] to point to available bodies: each
  // iov[i].iov_base will point to a body fragment, and iov[i].iov_len will be
  // set to its length.  No data is copied, no data is consumed.  Returns the
  // number of iov set.
  int PeekBody(iovec* iov, size_t iov_len) const;

  // Copies data from available bodies into at most |iov_len| elements of iov[].
  // Internally consumes copied body bytes as well as all interleaving and
  // immediately trailing non-body bytes.  |iov.iov_base| and |iov.iov_len| are
  // preassigned and will not be changed.  Returns the total number of bytes the
  // caller shall mark consumed.  Sets |*total_bytes_read| to the total number
  // of body bytes read.
  ABSL_MUST_USE_RESULT size_t ReadBody(const struct iovec* iov,
                                       size_t iov_len,
                                       size_t* total_bytes_read);

  bool HasBytesToRead() const { return !fragments_.empty(); }

  uint64_t total_body_bytes_received() const {
    return total_body_bytes_received_;
  }

 private:
  // A Fragment instance represents a body fragment with a count of bytes
  // received afterwards but before the next body fragment that can be marked
  // consumed as soon as all of the body fragment is read.
  struct QUIC_EXPORT_PRIVATE Fragment {
    // |body| must not be empty.
    absl::string_view body;
    // Might be zero.
    QuicByteCount trailing_non_body_byte_count;
  };
  // Queue of body fragments and trailing non-body byte counts.
  quiche::QuicheCircularDeque<Fragment> fragments_;
  // Total body bytes received.
  QuicByteCount total_body_bytes_received_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_HTTP_QUIC_SPDY_STREAM_BODY_MANAGER_H_