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 <string> 17 #include <vector> 18 19 #include "absl/strings/string_view.h" 20 #include "absl/types/optional.h" 21 #include "net/third_party/quiche/src/http2/decoder/http2_frame_decoder_listener.h" 22 #include "net/third_party/quiche/src/http2/http2_constants.h" 23 #include "net/third_party/quiche/src/http2/http2_structures.h" 24 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h" 25 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h" 26 27 namespace http2 { 28 namespace test { 29 30 class 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. 37 FrameParts(const Http2FrameHeader& header, absl::string_view payload); 38 39 // For use in tests where the expected frame has a variable size payload 40 // and may be padded. 41 FrameParts(const Http2FrameHeader& header, 42 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, 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; 104 void OnUnknownStart(const Http2FrameHeader& header) override; 105 void OnUnknownPayload(const char* data, size_t len) override; 106 void OnUnknownEnd() override; 107 void OnPaddingTooLong(const Http2FrameHeader& header, 108 size_t missing_length) override; 109 void OnFrameSizeError(const Http2FrameHeader& header) override; 110 AppendSetting(const Http2SettingFields & setting_fields)111 void AppendSetting(const Http2SettingFields& setting_fields) { 112 settings_.push_back(setting_fields); 113 } 114 GetFrameHeader()115 const Http2FrameHeader& GetFrameHeader() const { return frame_header_; } 116 GetOptPriority()117 absl::optional<Http2PriorityFields> GetOptPriority() const { 118 return opt_priority_; 119 } GetOptRstStreamErrorCode()120 absl::optional<Http2ErrorCode> GetOptRstStreamErrorCode() const { 121 return opt_rst_stream_error_code_; 122 } GetOptPushPromise()123 absl::optional<Http2PushPromiseFields> GetOptPushPromise() const { 124 return opt_push_promise_; 125 } GetOptPing()126 absl::optional<Http2PingFields> GetOptPing() const { return opt_ping_; } GetOptGoaway()127 absl::optional<Http2GoAwayFields> GetOptGoaway() const { return opt_goaway_; } GetOptPadLength()128 absl::optional<size_t> GetOptPadLength() const { return opt_pad_length_; } GetOptPayloadLength()129 absl::optional<size_t> GetOptPayloadLength() const { 130 return opt_payload_length_; 131 } GetOptMissingLength()132 absl::optional<size_t> GetOptMissingLength() const { 133 return opt_missing_length_; 134 } GetOptAltsvcOriginLength()135 absl::optional<size_t> GetOptAltsvcOriginLength() const { 136 return opt_altsvc_origin_length_; 137 } GetOptAltsvcValueLength()138 absl::optional<size_t> GetOptAltsvcValueLength() const { 139 return opt_altsvc_value_length_; 140 } GetOptWindowUpdateIncrement()141 absl::optional<size_t> GetOptWindowUpdateIncrement() const { 142 return opt_window_update_increment_; 143 } GetHasFrameSizeError()144 bool GetHasFrameSizeError() const { return has_frame_size_error_; } 145 SetOptPriority(absl::optional<Http2PriorityFields> opt_priority)146 void SetOptPriority(absl::optional<Http2PriorityFields> opt_priority) { 147 opt_priority_ = opt_priority; 148 } SetOptRstStreamErrorCode(absl::optional<Http2ErrorCode> opt_rst_stream_error_code)149 void SetOptRstStreamErrorCode( 150 absl::optional<Http2ErrorCode> opt_rst_stream_error_code) { 151 opt_rst_stream_error_code_ = opt_rst_stream_error_code; 152 } SetOptPushPromise(absl::optional<Http2PushPromiseFields> opt_push_promise)153 void SetOptPushPromise( 154 absl::optional<Http2PushPromiseFields> opt_push_promise) { 155 opt_push_promise_ = opt_push_promise; 156 } SetOptPing(absl::optional<Http2PingFields> opt_ping)157 void SetOptPing(absl::optional<Http2PingFields> opt_ping) { 158 opt_ping_ = opt_ping; 159 } SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway)160 void SetOptGoaway(absl::optional<Http2GoAwayFields> opt_goaway) { 161 opt_goaway_ = opt_goaway; 162 } SetOptPadLength(absl::optional<size_t> opt_pad_length)163 void SetOptPadLength(absl::optional<size_t> opt_pad_length) { 164 opt_pad_length_ = opt_pad_length; 165 } SetOptPayloadLength(absl::optional<size_t> opt_payload_length)166 void SetOptPayloadLength(absl::optional<size_t> opt_payload_length) { 167 opt_payload_length_ = opt_payload_length; 168 } SetOptMissingLength(absl::optional<size_t> opt_missing_length)169 void SetOptMissingLength(absl::optional<size_t> opt_missing_length) { 170 opt_missing_length_ = opt_missing_length; 171 } SetOptAltsvcOriginLength(absl::optional<size_t> opt_altsvc_origin_length)172 void SetOptAltsvcOriginLength( 173 absl::optional<size_t> opt_altsvc_origin_length) { 174 opt_altsvc_origin_length_ = opt_altsvc_origin_length; 175 } SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length)176 void SetOptAltsvcValueLength(absl::optional<size_t> opt_altsvc_value_length) { 177 opt_altsvc_value_length_ = opt_altsvc_value_length; 178 } SetOptWindowUpdateIncrement(absl::optional<size_t> opt_window_update_increment)179 void SetOptWindowUpdateIncrement( 180 absl::optional<size_t> opt_window_update_increment) { 181 opt_window_update_increment_ = opt_window_update_increment; 182 } 183 SetHasFrameSizeError(bool has_frame_size_error)184 void SetHasFrameSizeError(bool has_frame_size_error) { 185 has_frame_size_error_ = has_frame_size_error; 186 } 187 188 private: 189 // ASSERT during an On* method that we're handling a frame of type 190 // expected_frame_type, and have not already received other On* methods 191 // (i.e. got_start_callback is false). 192 ::testing::AssertionResult StartFrameOfType( 193 const Http2FrameHeader& header, 194 Http2FrameType expected_frame_type); 195 196 // ASSERT that StartFrameOfType has already been called with 197 // expected_frame_type (i.e. got_start_callback has been called), and that 198 // EndFrameOfType has not yet been called (i.e. got_end_callback is false). 199 ::testing::AssertionResult InFrameOfType(Http2FrameType expected_frame_type); 200 201 // ASSERT that we're InFrameOfType, and then sets got_end_callback=true. 202 ::testing::AssertionResult EndFrameOfType(Http2FrameType expected_frame_type); 203 204 // ASSERT that we're in the middle of processing a frame that is padded. 205 ::testing::AssertionResult InPaddedFrame(); 206 207 // Append source to target. If opt_length is not nullptr, then verifies that 208 // the optional has a value (i.e. that the necessary On*Start method has been 209 // called), and that target is not longer than opt_length->value(). 210 ::testing::AssertionResult AppendString(absl::string_view source, 211 std::string* target, 212 absl::optional<size_t>* opt_length); 213 214 const Http2FrameHeader frame_header_; 215 216 std::string payload_; 217 std::string padding_; 218 std::string altsvc_origin_; 219 std::string altsvc_value_; 220 221 absl::optional<Http2PriorityFields> opt_priority_; 222 absl::optional<Http2ErrorCode> opt_rst_stream_error_code_; 223 absl::optional<Http2PushPromiseFields> opt_push_promise_; 224 absl::optional<Http2PingFields> opt_ping_; 225 absl::optional<Http2GoAwayFields> opt_goaway_; 226 227 absl::optional<size_t> opt_pad_length_; 228 absl::optional<size_t> opt_payload_length_; 229 absl::optional<size_t> opt_missing_length_; 230 absl::optional<size_t> opt_altsvc_origin_length_; 231 absl::optional<size_t> opt_altsvc_value_length_; 232 233 absl::optional<size_t> opt_window_update_increment_; 234 235 bool has_frame_size_error_ = false; 236 237 std::vector<Http2SettingFields> settings_; 238 239 // These booleans are not checked by CompareCollectedFrames. 240 bool got_start_callback_ = false; 241 bool got_end_callback_ = false; 242 }; 243 244 std::ostream& operator<<(std::ostream& out, const FrameParts& v); 245 246 } // namespace test 247 } // namespace http2 248 249 #endif // QUICHE_HTTP2_TEST_TOOLS_FRAME_PARTS_H_ 250