xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/http2/test_tools/frame_parts.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 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_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
6 #define QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
7 
8 // FrameParts implements Http2FrameDecoderListener, recording the callbacks
9 // during the decoding of a single frame. It is also used for comparing the
10 // info that a test expects to be recorded during the decoding of a frame
11 // with the actual recorded value (i.e. by providing a comparator).
12 
13 #include <stddef.h>
14 
15 #include <cstdint>
16 #include <optional>
17 #include <string>
18 #include <vector>
19 
20 #include "absl/strings/string_view.h"
21 #include "quiche/http2/decoder/http2_frame_decoder_listener.h"
22 #include "quiche/http2/http2_constants.h"
23 #include "quiche/http2/http2_structures.h"
24 #include "quiche/common/platform/api/quiche_export.h"
25 #include "quiche/common/platform/api/quiche_logging.h"
26 #include "quiche/common/platform/api/quiche_test.h"
27 
28 namespace http2 {
29 namespace test {
30 
31 class QUICHE_NO_EXPORT FrameParts : public Http2FrameDecoderListener {
32  public:
33   // The first callback for every type of frame includes the frame header; this
34   // is the only constructor used during decoding of a frame.
35   explicit FrameParts(const Http2FrameHeader& header);
36 
37   // For use in tests where the expected frame has a variable size payload.
38   FrameParts(const Http2FrameHeader& header, absl::string_view payload);
39 
40   // For use in tests where the expected frame has a variable size payload
41   // and may be padded.
42   FrameParts(const Http2FrameHeader& header, absl::string_view payload,
43              size_t total_pad_length);
44 
45   // Copy constructor.
46   FrameParts(const FrameParts& header);
47 
48   ~FrameParts() override;
49 
50   // Returns AssertionSuccess() if they're equal, else AssertionFailure()
51   // with info about the difference.
52   ::testing::AssertionResult VerifyEquals(const FrameParts& other) const;
53 
54   // Format this FrameParts object.
55   void OutputTo(std::ostream& out) const;
56 
57   // Set the total padding length (0 to 256).
58   void SetTotalPadLength(size_t total_pad_length);
59 
60   // Set the origin and value expected in an ALTSVC frame.
61   void SetAltSvcExpected(absl::string_view origin, absl::string_view value);
62 
63   // Http2FrameDecoderListener methods:
64   bool OnFrameHeader(const Http2FrameHeader& header) override;
65   void OnDataStart(const Http2FrameHeader& header) override;
66   void OnDataPayload(const char* data, size_t len) override;
67   void OnDataEnd() override;
68   void OnHeadersStart(const Http2FrameHeader& header) override;
69   void OnHeadersPriority(const Http2PriorityFields& priority) override;
70   void OnHpackFragment(const char* data, size_t len) override;
71   void OnHeadersEnd() override;
72   void OnPriorityFrame(const Http2FrameHeader& header,
73                        const Http2PriorityFields& priority) override;
74   void OnContinuationStart(const Http2FrameHeader& header) override;
75   void OnContinuationEnd() override;
76   void OnPadLength(size_t trailing_length) override;
77   void OnPadding(const char* pad, size_t skipped_length) override;
78   void OnRstStream(const Http2FrameHeader& header,
79                    Http2ErrorCode error_code) override;
80   void OnSettingsStart(const Http2FrameHeader& header) override;
81   void OnSetting(const Http2SettingFields& setting_fields) override;
82   void OnSettingsEnd() override;
83   void OnSettingsAck(const Http2FrameHeader& header) override;
84   void OnPushPromiseStart(const Http2FrameHeader& header,
85                           const Http2PushPromiseFields& promise,
86                           size_t total_padding_length) override;
87   void OnPushPromiseEnd() override;
88   void OnPing(const Http2FrameHeader& header,
89               const Http2PingFields& ping) override;
90   void OnPingAck(const Http2FrameHeader& header,
91                  const Http2PingFields& ping) override;
92   void OnGoAwayStart(const Http2FrameHeader& header,
93                      const Http2GoAwayFields& goaway) override;
94   void OnGoAwayOpaqueData(const char* data, size_t len) override;
95   void OnGoAwayEnd() override;
96   void OnWindowUpdate(const Http2FrameHeader& header,
97                       uint32_t increment) override;
98   void OnAltSvcStart(const Http2FrameHeader& header, size_t origin_length,
99                      size_t value_length) override;
100   void OnAltSvcOriginData(const char* data, size_t len) override;
101   void OnAltSvcValueData(const char* data, size_t len) override;
102   void OnAltSvcEnd() override;
103   void OnPriorityUpdateStart(
104       const Http2FrameHeader& header,
105       const Http2PriorityUpdateFields& priority_update) override;
106   void OnPriorityUpdatePayload(const char* data, size_t len) override;
107   void OnPriorityUpdateEnd() override;
108   void OnUnknownStart(const Http2FrameHeader& header) override;
109   void OnUnknownPayload(const char* data, size_t len) override;
110   void OnUnknownEnd() override;
111   void OnPaddingTooLong(const Http2FrameHeader& header,
112                         size_t missing_length) override;
113   void OnFrameSizeError(const Http2FrameHeader& header) override;
114 
AppendSetting(const Http2SettingFields & setting_fields)115   void AppendSetting(const Http2SettingFields& setting_fields) {
116     settings_.push_back(setting_fields);
117   }
118 
GetFrameHeader()119   const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
120 
GetOptPriority()121   std::optional<Http2PriorityFields> GetOptPriority() const {
122     return opt_priority_;
123   }
GetOptRstStreamErrorCode()124   std::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
125     return opt_rst_stream_error_code_;
126   }
GetOptPushPromise()127   std::optional<Http2PushPromiseFields> GetOptPushPromise() const {
128     return opt_push_promise_;
129   }
GetOptPing()130   std::optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
GetOptGoaway()131   std::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
GetOptPadLength()132   std::optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
GetOptPayloadLength()133   std::optional<size_t> GetOptPayloadLength() const {
134     return opt_payload_length_;
135   }
GetOptMissingLength()136   std::optional<size_t> GetOptMissingLength() const {
137     return opt_missing_length_;
138   }
GetOptAltsvcOriginLength()139   std::optional<size_t> GetOptAltsvcOriginLength() const {
140     return opt_altsvc_origin_length_;
141   }
GetOptAltsvcValueLength()142   std::optional<size_t> GetOptAltsvcValueLength() const {
143     return opt_altsvc_value_length_;
144   }
GetOptWindowUpdateIncrement()145   std::optional<size_t> GetOptWindowUpdateIncrement() const {
146     return opt_window_update_increment_;
147   }
GetHasFrameSizeError()148   bool GetHasFrameSizeError() const { return has_frame_size_error_; }
149 
SetOptPriority(std::optional<Http2PriorityFields> opt_priority)150   void SetOptPriority(std::optional<Http2PriorityFields> opt_priority) {
151     opt_priority_ = opt_priority;
152   }
SetOptRstStreamErrorCode(std::optional<Http2ErrorCode> opt_rst_stream_error_code)153   void SetOptRstStreamErrorCode(
154       std::optional<Http2ErrorCode> opt_rst_stream_error_code) {
155     opt_rst_stream_error_code_ = opt_rst_stream_error_code;
156   }
SetOptPushPromise(std::optional<Http2PushPromiseFields> opt_push_promise)157   void SetOptPushPromise(
158       std::optional<Http2PushPromiseFields> opt_push_promise) {
159     opt_push_promise_ = opt_push_promise;
160   }
SetOptPing(std::optional<Http2PingFields> opt_ping)161   void SetOptPing(std::optional<Http2PingFields> opt_ping) {
162     opt_ping_ = opt_ping;
163   }
SetOptGoaway(std::optional<Http2GoAwayFields> opt_goaway)164   void SetOptGoaway(std::optional<Http2GoAwayFields> opt_goaway) {
165     opt_goaway_ = opt_goaway;
166   }
SetOptPadLength(std::optional<size_t> opt_pad_length)167   void SetOptPadLength(std::optional<size_t> opt_pad_length) {
168     opt_pad_length_ = opt_pad_length;
169   }
SetOptPayloadLength(std::optional<size_t> opt_payload_length)170   void SetOptPayloadLength(std::optional<size_t> opt_payload_length) {
171     opt_payload_length_ = opt_payload_length;
172   }
SetOptMissingLength(std::optional<size_t> opt_missing_length)173   void SetOptMissingLength(std::optional<size_t> opt_missing_length) {
174     opt_missing_length_ = opt_missing_length;
175   }
SetOptAltsvcOriginLength(std::optional<size_t> opt_altsvc_origin_length)176   void SetOptAltsvcOriginLength(
177       std::optional<size_t> opt_altsvc_origin_length) {
178     opt_altsvc_origin_length_ = opt_altsvc_origin_length;
179   }
SetOptAltsvcValueLength(std::optional<size_t> opt_altsvc_value_length)180   void SetOptAltsvcValueLength(std::optional<size_t> opt_altsvc_value_length) {
181     opt_altsvc_value_length_ = opt_altsvc_value_length;
182   }
SetOptWindowUpdateIncrement(std::optional<size_t> opt_window_update_increment)183   void SetOptWindowUpdateIncrement(
184       std::optional<size_t> opt_window_update_increment) {
185     opt_window_update_increment_ = opt_window_update_increment;
186   }
SetOptPriorityUpdate(std::optional<Http2PriorityUpdateFields> priority_update)187   void SetOptPriorityUpdate(
188       std::optional<Http2PriorityUpdateFields> priority_update) {
189     opt_priority_update_ = priority_update;
190   }
191 
SetHasFrameSizeError(bool has_frame_size_error)192   void SetHasFrameSizeError(bool has_frame_size_error) {
193     has_frame_size_error_ = has_frame_size_error;
194   }
195 
196  private:
197   // ASSERT during an On* method that we're handling a frame of type
198   // expected_frame_type, and have not already received other On* methods
199   // (i.e. got_start_callback is false).
200   ::testing::AssertionResult StartFrameOfType(
201       const Http2FrameHeader& header, Http2FrameType expected_frame_type);
202 
203   // ASSERT that StartFrameOfType has already been called with
204   // expected_frame_type (i.e. got_start_callback has been called), and that
205   // EndFrameOfType has not yet been called (i.e. got_end_callback is false).
206   ::testing::AssertionResult InFrameOfType(Http2FrameType expected_frame_type);
207 
208   // ASSERT that we're InFrameOfType, and then sets got_end_callback=true.
209   ::testing::AssertionResult EndFrameOfType(Http2FrameType expected_frame_type);
210 
211   // ASSERT that we're in the middle of processing a frame that is padded.
212   ::testing::AssertionResult InPaddedFrame();
213 
214   // Append source to target. If opt_length is not nullptr, then verifies that
215   // the optional has a value (i.e. that the necessary On*Start method has been
216   // called), and that target is not longer than opt_length->value().
217   ::testing::AssertionResult AppendString(absl::string_view source,
218                                           std::string* target,
219                                           std::optional<size_t>* opt_length);
220 
221   const Http2FrameHeader frame_header_;
222 
223   std::string payload_;
224   std::string padding_;
225   std::string altsvc_origin_;
226   std::string altsvc_value_;
227 
228   std::optional<Http2PriorityFields> opt_priority_;
229   std::optional<Http2ErrorCode> opt_rst_stream_error_code_;
230   std::optional<Http2PushPromiseFields> opt_push_promise_;
231   std::optional<Http2PingFields> opt_ping_;
232   std::optional<Http2GoAwayFields> opt_goaway_;
233   std::optional<Http2PriorityUpdateFields> opt_priority_update_;
234 
235   std::optional<size_t> opt_pad_length_;
236   std::optional<size_t> opt_payload_length_;
237   std::optional<size_t> opt_missing_length_;
238   std::optional<size_t> opt_altsvc_origin_length_;
239   std::optional<size_t> opt_altsvc_value_length_;
240 
241   std::optional<size_t> opt_window_update_increment_;
242 
243   bool has_frame_size_error_ = false;
244 
245   std::vector<Http2SettingFields> settings_;
246 
247   // These booleans are not checked by CompareCollectedFrames.
248   bool got_start_callback_ = false;
249   bool got_end_callback_ = false;
250 };
251 
252 QUICHE_NO_EXPORT std::ostream& operator<<(std::ostream& out,
253                                           const FrameParts& v);
254 
255 }  // namespace test
256 }  // namespace http2
257 
258 #endif  // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_
259