blob: 1cc69286aa18cbfaf39b17da8379c01949db99cf [file] [log] [blame]
QUICHE teamfd50a402018-12-07 22:54:05 -05001// 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>
bnc47904002019-08-16 11:49:48 -070016#include <string>
QUICHE teamfd50a402018-12-07 22:54:05 -050017#include <vector>
18
vasilvv015e16a2020-10-12 23:51:06 -070019#include "absl/strings/string_view.h"
vasilvv7df418b2020-10-13 13:47:09 -070020#include "absl/types/optional.h"
QUICHE team5be974e2020-12-29 18:35:24 -050021#include "http2/decoder/http2_frame_decoder_listener.h"
22#include "http2/http2_constants.h"
23#include "http2/http2_structures.h"
24#include "http2/platform/api/http2_logging.h"
25#include "common/platform/api/quiche_test.h"
QUICHE teamfd50a402018-12-07 22:54:05 -050026
27namespace http2 {
28namespace test {
29
30class FrameParts : public Http2FrameDecoderListener {
31 public:
32 // The first callback for every type of frame includes the frame header; this
33 // is the only constructor used during decoding of a frame.
34 explicit FrameParts(const Http2FrameHeader& header);
35
36 // For use in tests where the expected frame has a variable size payload.
vasilvv015e16a2020-10-12 23:51:06 -070037 FrameParts(const Http2FrameHeader& header, absl::string_view payload);
QUICHE teamfd50a402018-12-07 22:54:05 -050038
39 // For use in tests where the expected frame has a variable size payload
40 // and may be padded.
41 FrameParts(const Http2FrameHeader& header,
vasilvv015e16a2020-10-12 23:51:06 -070042 absl::string_view payload,
QUICHE teamfd50a402018-12-07 22:54:05 -050043 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.
vasilvv015e16a2020-10-12 23:51:06 -070061 void SetAltSvcExpected(absl::string_view origin, absl::string_view value);
QUICHE teamfd50a402018-12-07 22:54:05 -050062
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,
99 size_t origin_length,
100 size_t value_length) override;
101 void OnAltSvcOriginData(const char* data, size_t len) override;
102 void OnAltSvcValueData(const char* data, size_t len) override;
103 void OnAltSvcEnd() override;
bncbea13b82021-01-08 08:46:09 -0800104 void OnPriorityUpdateStart(
105 const Http2FrameHeader& header,
106 const Http2PriorityUpdateFields& priority_update) override;
107 void OnPriorityUpdatePayload(const char* data, size_t len) override;
108 void OnPriorityUpdateEnd() override;
QUICHE teamfd50a402018-12-07 22:54:05 -0500109 void OnUnknownStart(const Http2FrameHeader& header) override;
110 void OnUnknownPayload(const char* data, size_t len) override;
111 void OnUnknownEnd() override;
112 void OnPaddingTooLong(const Http2FrameHeader& header,
113 size_t missing_length) override;
114 void OnFrameSizeError(const Http2FrameHeader& header) override;
115
116 void AppendSetting(const Http2SettingFields& setting_fields) {
117 settings_.push_back(setting_fields);
118 }
119
120 const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
121
vasilvv7df418b2020-10-13 13:47:09 -0700122 absl::optional<Http2PriorityFields> GetOptPriority() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500123 return opt_priority_;
124 }
vasilvv7df418b2020-10-13 13:47:09 -0700125 absl::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500126 return opt_rst_stream_error_code_;
127 }
vasilvv7df418b2020-10-13 13:47:09 -0700128 absl::optional<Http2PushPromiseFields> GetOptPushPromise() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500129 return opt_push_promise_;
130 }
vasilvv7df418b2020-10-13 13:47:09 -0700131 absl::optional<Http2PingFields> GetOptPing() const { return opt_ping_; }
132 absl::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; }
133 absl::optional<size_t> GetOptPadLength() const { return opt_pad_length_; }
134 absl::optional<size_t> GetOptPayloadLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500135 return opt_payload_length_;
136 }
vasilvv7df418b2020-10-13 13:47:09 -0700137 absl::optional<size_t> GetOptMissingLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500138 return opt_missing_length_;
139 }
vasilvv7df418b2020-10-13 13:47:09 -0700140 absl::optional<size_t> GetOptAltsvcOriginLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500141 return opt_altsvc_origin_length_;
142 }
vasilvv7df418b2020-10-13 13:47:09 -0700143 absl::optional<size_t> GetOptAltsvcValueLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500144 return opt_altsvc_value_length_;
145 }
vasilvv7df418b2020-10-13 13:47:09 -0700146 absl::optional<size_t> GetOptWindowUpdateIncrement() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500147 return opt_window_update_increment_;
148 }
149 bool GetHasFrameSizeError() const { return has_frame_size_error_; }
150
vasilvv7df418b2020-10-13 13:47:09 -0700151 void SetOptPriority(absl::optional<Http2PriorityFields> opt_priority) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500152 opt_priority_ = opt_priority;
153 }
154 void SetOptRstStreamErrorCode(
vasilvv7df418b2020-10-13 13:47:09 -0700155 absl::optional<Http2ErrorCode> opt_rst_stream_error_code) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500156 opt_rst_stream_error_code_ = opt_rst_stream_error_code;
157 }
158 void SetOptPushPromise(
vasilvv7df418b2020-10-13 13:47:09 -0700159 absl::optional<Http2PushPromiseFields> opt_push_promise) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500160 opt_push_promise_ = opt_push_promise;
161 }
vasilvv7df418b2020-10-13 13:47:09 -0700162 void SetOptPing(absl::optional<Http2PingFields> opt_ping) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500163 opt_ping_ = opt_ping;
164 }
vasilvv7df418b2020-10-13 13:47:09 -0700165 void SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500166 opt_goaway_ = opt_goaway;
167 }
vasilvv7df418b2020-10-13 13:47:09 -0700168 void SetOptPadLength(absl::optional<size_t> opt_pad_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500169 opt_pad_length_ = opt_pad_length;
170 }
vasilvv7df418b2020-10-13 13:47:09 -0700171 void SetOptPayloadLength(absl::optional<size_t> opt_payload_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500172 opt_payload_length_ = opt_payload_length;
173 }
vasilvv7df418b2020-10-13 13:47:09 -0700174 void SetOptMissingLength(absl::optional<size_t> opt_missing_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500175 opt_missing_length_ = opt_missing_length;
176 }
177 void SetOptAltsvcOriginLength(
vasilvv7df418b2020-10-13 13:47:09 -0700178 absl::optional<size_t> opt_altsvc_origin_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500179 opt_altsvc_origin_length_ = opt_altsvc_origin_length;
180 }
vasilvv7df418b2020-10-13 13:47:09 -0700181 void SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500182 opt_altsvc_value_length_ = opt_altsvc_value_length;
183 }
184 void SetOptWindowUpdateIncrement(
vasilvv7df418b2020-10-13 13:47:09 -0700185 absl::optional<size_t> opt_window_update_increment) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500186 opt_window_update_increment_ = opt_window_update_increment;
187 }
bncbea13b82021-01-08 08:46:09 -0800188 void SetOptPriorityUpdate(
189 absl::optional<Http2PriorityUpdateFields> priority_update) {
190 opt_priority_update_ = priority_update;
191 }
QUICHE teamfd50a402018-12-07 22:54:05 -0500192
193 void SetHasFrameSizeError(bool has_frame_size_error) {
194 has_frame_size_error_ = has_frame_size_error;
195 }
196
197 private:
198 // ASSERT during an On* method that we're handling a frame of type
199 // expected_frame_type, and have not already received other On* methods
200 // (i.e. got_start_callback is false).
201 ::testing::AssertionResult StartFrameOfType(
202 const Http2FrameHeader& header,
203 Http2FrameType expected_frame_type);
204
205 // ASSERT that StartFrameOfType has already been called with
206 // expected_frame_type (i.e. got_start_callback has been called), and that
207 // EndFrameOfType has not yet been called (i.e. got_end_callback is false).
208 ::testing::AssertionResult InFrameOfType(Http2FrameType expected_frame_type);
209
210 // ASSERT that we're InFrameOfType, and then sets got_end_callback=true.
211 ::testing::AssertionResult EndFrameOfType(Http2FrameType expected_frame_type);
212
213 // ASSERT that we're in the middle of processing a frame that is padded.
214 ::testing::AssertionResult InPaddedFrame();
215
216 // Append source to target. If opt_length is not nullptr, then verifies that
217 // the optional has a value (i.e. that the necessary On*Start method has been
218 // called), and that target is not longer than opt_length->value().
vasilvv7df418b2020-10-13 13:47:09 -0700219 ::testing::AssertionResult AppendString(absl::string_view source,
220 std::string* target,
221 absl::optional<size_t>* opt_length);
QUICHE teamfd50a402018-12-07 22:54:05 -0500222
223 const Http2FrameHeader frame_header_;
224
bnc47904002019-08-16 11:49:48 -0700225 std::string payload_;
226 std::string padding_;
227 std::string altsvc_origin_;
228 std::string altsvc_value_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500229
vasilvv7df418b2020-10-13 13:47:09 -0700230 absl::optional<Http2PriorityFields> opt_priority_;
231 absl::optional<Http2ErrorCode> opt_rst_stream_error_code_;
232 absl::optional<Http2PushPromiseFields> opt_push_promise_;
233 absl::optional<Http2PingFields> opt_ping_;
234 absl::optional<Http2GoAwayFields> opt_goaway_;
bncbea13b82021-01-08 08:46:09 -0800235 absl::optional<Http2PriorityUpdateFields> opt_priority_update_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500236
vasilvv7df418b2020-10-13 13:47:09 -0700237 absl::optional<size_t> opt_pad_length_;
238 absl::optional<size_t> opt_payload_length_;
239 absl::optional<size_t> opt_missing_length_;
240 absl::optional<size_t> opt_altsvc_origin_length_;
241 absl::optional<size_t> opt_altsvc_value_length_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500242
vasilvv7df418b2020-10-13 13:47:09 -0700243 absl::optional<size_t> opt_window_update_increment_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500244
245 bool has_frame_size_error_ = false;
246
247 std::vector<Http2SettingFields> settings_;
248
249 // These booleans are not checked by CompareCollectedFrames.
250 bool got_start_callback_ = false;
251 bool got_end_callback_ = false;
252};
253
254std::ostream& operator<<(std::ostream& out, const FrameParts& v);
255
256} // namespace test
257} // namespace http2
258
259#endif // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_