blob: 68e54824a9f3e588b4c3125596a8791dba42dc8f [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
QUICHE teamfd50a402018-12-07 22:54:05 -050019#include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h"
20#include "net/third_party/quiche/src/http2/http2_constants.h"
21#include "net/third_party/quiche/src/http2/http2_structures.h"
QUICHE team61940b42019-03-07 23:32:27 -050022#include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
bnc766e81c2020-01-15 07:16:52 -080023#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
bnc74646d12019-12-13 09:21:19 -080024#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
bnc6744c062020-09-30 10:45:28 -070025#include "net/third_party/quiche/src/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.
bnc74646d12019-12-13 09:21:19 -080037 FrameParts(const Http2FrameHeader& header, quiche::QuicheStringPiece 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,
bnc74646d12019-12-13 09:21:19 -080042 quiche::QuicheStringPiece 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.
bnc74646d12019-12-13 09:21:19 -080061 void SetAltSvcExpected(quiche::QuicheStringPiece origin,
62 quiche::QuicheStringPiece value);
QUICHE teamfd50a402018-12-07 22:54:05 -050063
64 // Http2FrameDecoderListener methods:
65 bool OnFrameHeader(const Http2FrameHeader& header) override;
66 void OnDataStart(const Http2FrameHeader& header) override;
67 void OnDataPayload(const char* data, size_t len) override;
68 void OnDataEnd() override;
69 void OnHeadersStart(const Http2FrameHeader& header) override;
70 void OnHeadersPriority(const Http2PriorityFields& priority) override;
71 void OnHpackFragment(const char* data, size_t len) override;
72 void OnHeadersEnd() override;
73 void OnPriorityFrame(const Http2FrameHeader& header,
74 const Http2PriorityFields& priority) override;
75 void OnContinuationStart(const Http2FrameHeader& header) override;
76 void OnContinuationEnd() override;
77 void OnPadLength(size_t trailing_length) override;
78 void OnPadding(const char* pad, size_t skipped_length) override;
79 void OnRstStream(const Http2FrameHeader& header,
80 Http2ErrorCode error_code) override;
81 void OnSettingsStart(const Http2FrameHeader& header) override;
82 void OnSetting(const Http2SettingFields& setting_fields) override;
83 void OnSettingsEnd() override;
84 void OnSettingsAck(const Http2FrameHeader& header) override;
85 void OnPushPromiseStart(const Http2FrameHeader& header,
86 const Http2PushPromiseFields& promise,
87 size_t total_padding_length) override;
88 void OnPushPromiseEnd() override;
89 void OnPing(const Http2FrameHeader& header,
90 const Http2PingFields& ping) override;
91 void OnPingAck(const Http2FrameHeader& header,
92 const Http2PingFields& ping) override;
93 void OnGoAwayStart(const Http2FrameHeader& header,
94 const Http2GoAwayFields& goaway) override;
95 void OnGoAwayOpaqueData(const char* data, size_t len) override;
96 void OnGoAwayEnd() override;
97 void OnWindowUpdate(const Http2FrameHeader& header,
98 uint32_t increment) override;
99 void OnAltSvcStart(const Http2FrameHeader& header,
100 size_t origin_length,
101 size_t value_length) override;
102 void OnAltSvcOriginData(const char* data, size_t len) override;
103 void OnAltSvcValueData(const char* data, size_t len) override;
104 void OnAltSvcEnd() override;
105 void OnUnknownStart(const Http2FrameHeader& header) override;
106 void OnUnknownPayload(const char* data, size_t len) override;
107 void OnUnknownEnd() override;
108 void OnPaddingTooLong(const Http2FrameHeader& header,
109 size_t missing_length) override;
110 void OnFrameSizeError(const Http2FrameHeader& header) override;
111
112 void AppendSetting(const Http2SettingFields& setting_fields) {
113 settings_.push_back(setting_fields);
114 }
115
116 const Http2FrameHeader& GetFrameHeader() const { return frame_header_; }
117
bnc766e81c2020-01-15 07:16:52 -0800118 quiche::QuicheOptional<Http2PriorityFields> GetOptPriority() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500119 return opt_priority_;
120 }
bnc766e81c2020-01-15 07:16:52 -0800121 quiche::QuicheOptional<Http2ErrorCode> GetOptRstStreamErrorCode() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500122 return opt_rst_stream_error_code_;
123 }
bnc766e81c2020-01-15 07:16:52 -0800124 quiche::QuicheOptional<Http2PushPromiseFields> GetOptPushPromise() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500125 return opt_push_promise_;
126 }
bnc766e81c2020-01-15 07:16:52 -0800127 quiche::QuicheOptional<Http2PingFields> GetOptPing() const {
128 return opt_ping_;
129 }
130 quiche::QuicheOptional<Http2GoAwayFields> GetOptGoaway() const {
131 return opt_goaway_;
132 }
133 quiche::QuicheOptional<size_t> GetOptPadLength() const {
134 return opt_pad_length_;
135 }
136 quiche::QuicheOptional<size_t> GetOptPayloadLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500137 return opt_payload_length_;
138 }
bnc766e81c2020-01-15 07:16:52 -0800139 quiche::QuicheOptional<size_t> GetOptMissingLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500140 return opt_missing_length_;
141 }
bnc766e81c2020-01-15 07:16:52 -0800142 quiche::QuicheOptional<size_t> GetOptAltsvcOriginLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500143 return opt_altsvc_origin_length_;
144 }
bnc766e81c2020-01-15 07:16:52 -0800145 quiche::QuicheOptional<size_t> GetOptAltsvcValueLength() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500146 return opt_altsvc_value_length_;
147 }
bnc766e81c2020-01-15 07:16:52 -0800148 quiche::QuicheOptional<size_t> GetOptWindowUpdateIncrement() const {
QUICHE teamfd50a402018-12-07 22:54:05 -0500149 return opt_window_update_increment_;
150 }
151 bool GetHasFrameSizeError() const { return has_frame_size_error_; }
152
bnc766e81c2020-01-15 07:16:52 -0800153 void SetOptPriority(
154 quiche::QuicheOptional<Http2PriorityFields> opt_priority) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500155 opt_priority_ = opt_priority;
156 }
157 void SetOptRstStreamErrorCode(
bnc766e81c2020-01-15 07:16:52 -0800158 quiche::QuicheOptional<Http2ErrorCode> opt_rst_stream_error_code) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500159 opt_rst_stream_error_code_ = opt_rst_stream_error_code;
160 }
161 void SetOptPushPromise(
bnc766e81c2020-01-15 07:16:52 -0800162 quiche::QuicheOptional<Http2PushPromiseFields> opt_push_promise) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500163 opt_push_promise_ = opt_push_promise;
164 }
bnc766e81c2020-01-15 07:16:52 -0800165 void SetOptPing(quiche::QuicheOptional<Http2PingFields> opt_ping) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500166 opt_ping_ = opt_ping;
167 }
bnc766e81c2020-01-15 07:16:52 -0800168 void SetOptGoaway(quiche::QuicheOptional<Http2GoAwayFields> opt_goaway) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500169 opt_goaway_ = opt_goaway;
170 }
bnc766e81c2020-01-15 07:16:52 -0800171 void SetOptPadLength(quiche::QuicheOptional<size_t> opt_pad_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500172 opt_pad_length_ = opt_pad_length;
173 }
bnc766e81c2020-01-15 07:16:52 -0800174 void SetOptPayloadLength(quiche::QuicheOptional<size_t> opt_payload_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500175 opt_payload_length_ = opt_payload_length;
176 }
bnc766e81c2020-01-15 07:16:52 -0800177 void SetOptMissingLength(quiche::QuicheOptional<size_t> opt_missing_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500178 opt_missing_length_ = opt_missing_length;
179 }
180 void SetOptAltsvcOriginLength(
bnc766e81c2020-01-15 07:16:52 -0800181 quiche::QuicheOptional<size_t> opt_altsvc_origin_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500182 opt_altsvc_origin_length_ = opt_altsvc_origin_length;
183 }
bnc766e81c2020-01-15 07:16:52 -0800184 void SetOptAltsvcValueLength(
185 quiche::QuicheOptional<size_t> opt_altsvc_value_length) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500186 opt_altsvc_value_length_ = opt_altsvc_value_length;
187 }
188 void SetOptWindowUpdateIncrement(
bnc766e81c2020-01-15 07:16:52 -0800189 quiche::QuicheOptional<size_t> opt_window_update_increment) {
QUICHE teamfd50a402018-12-07 22:54:05 -0500190 opt_window_update_increment_ = opt_window_update_increment;
191 }
192
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().
bnc766e81c2020-01-15 07:16:52 -0800219 ::testing::AssertionResult AppendString(
220 quiche::QuicheStringPiece source,
221 std::string* target,
222 quiche::QuicheOptional<size_t>* opt_length);
QUICHE teamfd50a402018-12-07 22:54:05 -0500223
224 const Http2FrameHeader frame_header_;
225
bnc47904002019-08-16 11:49:48 -0700226 std::string payload_;
227 std::string padding_;
228 std::string altsvc_origin_;
229 std::string altsvc_value_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500230
bnc766e81c2020-01-15 07:16:52 -0800231 quiche::QuicheOptional<Http2PriorityFields> opt_priority_;
232 quiche::QuicheOptional<Http2ErrorCode> opt_rst_stream_error_code_;
233 quiche::QuicheOptional<Http2PushPromiseFields> opt_push_promise_;
234 quiche::QuicheOptional<Http2PingFields> opt_ping_;
235 quiche::QuicheOptional<Http2GoAwayFields> opt_goaway_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500236
bnc766e81c2020-01-15 07:16:52 -0800237 quiche::QuicheOptional<size_t> opt_pad_length_;
238 quiche::QuicheOptional<size_t> opt_payload_length_;
239 quiche::QuicheOptional<size_t> opt_missing_length_;
240 quiche::QuicheOptional<size_t> opt_altsvc_origin_length_;
241 quiche::QuicheOptional<size_t> opt_altsvc_value_length_;
QUICHE teamfd50a402018-12-07 22:54:05 -0500242
bnc766e81c2020-01-15 07:16:52 -0800243 quiche::QuicheOptional<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_