OLD | NEW |
(Empty) | |
| 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 #include "net/http2/decoder/frame_parts.h" |
| 6 |
| 7 #include <type_traits> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "net/base/escape.h" |
| 11 #include "net/http2/http2_structures_test_util.h" |
| 12 #include "net/http2/tools/failure.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 |
| 15 using base::StringPiece; |
| 16 using std::string; |
| 17 using ::testing::AssertionFailure; |
| 18 using ::testing::AssertionResult; |
| 19 using ::testing::AssertionSuccess; |
| 20 using ::testing::ContainerEq; |
| 21 |
| 22 namespace net { |
| 23 namespace test { |
| 24 namespace { |
| 25 |
| 26 static_assert(std::is_base_of<Http2FrameDecoderListener, FrameParts>::value && |
| 27 !std::is_abstract<FrameParts>::value, |
| 28 "FrameParts needs to implement all of the methods of " |
| 29 "Http2FrameDecoderListener"); |
| 30 |
| 31 // Compare two optional variables of the same type. |
| 32 // TODO(jamessynge): Maybe create a ::testing::Matcher for this. |
| 33 template <class T> |
| 34 AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) { |
| 35 if (opt_a) { |
| 36 if (opt_b) { |
| 37 VERIFY_EQ(opt_a.value(), opt_b.value()); |
| 38 } else { |
| 39 return AssertionFailure() << "opt_b is not set; opt_a.value()=" |
| 40 << opt_a.value(); |
| 41 } |
| 42 } else if (opt_b) { |
| 43 return AssertionFailure() << "opt_a is not set; opt_b.value()=" |
| 44 << opt_b.value(); |
| 45 } |
| 46 return AssertionSuccess(); |
| 47 } |
| 48 |
| 49 } // namespace |
| 50 |
| 51 FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header(header) { |
| 52 VLOG(1) << "FrameParts, header: " << frame_header; |
| 53 } |
| 54 |
| 55 FrameParts::FrameParts(const Http2FrameHeader& header, StringPiece payload) |
| 56 : FrameParts(header) { |
| 57 VLOG(1) << "FrameParts with payload.size() = " << payload.size(); |
| 58 payload.AppendToString(&this->payload); |
| 59 opt_payload_length = payload.size(); |
| 60 } |
| 61 FrameParts::FrameParts(const Http2FrameHeader& header, |
| 62 StringPiece payload, |
| 63 size_t total_pad_length) |
| 64 : FrameParts(header, payload) { |
| 65 VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length; |
| 66 SetTotalPadLength(total_pad_length); |
| 67 } |
| 68 |
| 69 FrameParts::FrameParts(const FrameParts& other) = default; |
| 70 |
| 71 FrameParts::~FrameParts() {} |
| 72 |
| 73 AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const { |
| 74 #define COMMON_MESSAGE "\n this: " << *this << "\n that: " << that |
| 75 |
| 76 VERIFY_EQ(frame_header, that.frame_header) << COMMON_MESSAGE; |
| 77 VERIFY_EQ(payload, that.payload) << COMMON_MESSAGE; |
| 78 VERIFY_EQ(padding, that.padding) << COMMON_MESSAGE; |
| 79 VERIFY_EQ(altsvc_origin, that.altsvc_origin) << COMMON_MESSAGE; |
| 80 VERIFY_EQ(altsvc_value, that.altsvc_value) << COMMON_MESSAGE; |
| 81 VERIFY_EQ(settings, that.settings) << COMMON_MESSAGE; |
| 82 |
| 83 #define VERIFY_OPTIONAL_FIELD(field_name) \ |
| 84 VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name)) |
| 85 |
| 86 VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length) << COMMON_MESSAGE; |
| 87 VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length) << COMMON_MESSAGE; |
| 88 VERIFY_OPTIONAL_FIELD(opt_goaway) << COMMON_MESSAGE; |
| 89 VERIFY_OPTIONAL_FIELD(opt_missing_length) << COMMON_MESSAGE; |
| 90 VERIFY_OPTIONAL_FIELD(opt_pad_length) << COMMON_MESSAGE; |
| 91 VERIFY_OPTIONAL_FIELD(opt_ping) << COMMON_MESSAGE; |
| 92 VERIFY_OPTIONAL_FIELD(opt_priority) << COMMON_MESSAGE; |
| 93 VERIFY_OPTIONAL_FIELD(opt_push_promise) << COMMON_MESSAGE; |
| 94 VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code) << COMMON_MESSAGE; |
| 95 VERIFY_OPTIONAL_FIELD(opt_window_update_increment) << COMMON_MESSAGE; |
| 96 |
| 97 #undef VERIFY_OPTIONAL_FIELD |
| 98 |
| 99 return AssertionSuccess(); |
| 100 } |
| 101 |
| 102 void FrameParts::SetTotalPadLength(size_t total_pad_length) { |
| 103 opt_pad_length.reset(); |
| 104 padding.clear(); |
| 105 if (total_pad_length > 0) { |
| 106 ASSERT_LE(total_pad_length, 256u); |
| 107 ASSERT_TRUE(frame_header.IsPadded()); |
| 108 opt_pad_length = total_pad_length - 1; |
| 109 char zero = 0; |
| 110 padding.append(opt_pad_length.value(), zero); |
| 111 } |
| 112 |
| 113 if (opt_pad_length) { |
| 114 VLOG(1) << "SetTotalPadLength: pad_length=" << opt_pad_length.value(); |
| 115 } else { |
| 116 VLOG(1) << "SetTotalPadLength: has no pad length"; |
| 117 } |
| 118 } |
| 119 |
| 120 void FrameParts::SetAltSvcExpected(StringPiece origin, StringPiece value) { |
| 121 origin.AppendToString(&altsvc_origin); |
| 122 value.AppendToString(&altsvc_value); |
| 123 opt_altsvc_origin_length = origin.size(); |
| 124 opt_altsvc_value_length = value.size(); |
| 125 } |
| 126 |
| 127 bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) { |
| 128 ADD_FAILURE() << "OnFrameHeader: " << *this; |
| 129 return true; |
| 130 } |
| 131 |
| 132 void FrameParts::OnDataStart(const Http2FrameHeader& header) { |
| 133 VLOG(1) << "OnDataStart: " << header; |
| 134 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this; |
| 135 opt_payload_length = header.payload_length; |
| 136 } |
| 137 |
| 138 void FrameParts::OnDataPayload(const char* data, size_t len) { |
| 139 VLOG(1) << "OnDataPayload: len=" << len << "; frame_header: " << frame_header; |
| 140 ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this; |
| 141 ASSERT_TRUE( |
| 142 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); |
| 143 } |
| 144 |
| 145 void FrameParts::OnDataEnd() { |
| 146 VLOG(1) << "OnDataEnd; frame_header: " << frame_header; |
| 147 ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this; |
| 148 } |
| 149 |
| 150 void FrameParts::OnHeadersStart(const Http2FrameHeader& header) { |
| 151 VLOG(1) << "OnHeadersStart: " << header; |
| 152 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this; |
| 153 opt_payload_length = header.payload_length; |
| 154 } |
| 155 |
| 156 void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) { |
| 157 VLOG(1) << "OnHeadersPriority: priority: " << priority |
| 158 << "; frame_header: " << frame_header; |
| 159 ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this; |
| 160 ASSERT_FALSE(opt_priority); |
| 161 opt_priority = priority; |
| 162 ASSERT_TRUE(opt_payload_length); |
| 163 opt_payload_length = |
| 164 opt_payload_length.value() - Http2PriorityFields::EncodedSize(); |
| 165 } |
| 166 |
| 167 void FrameParts::OnHpackFragment(const char* data, size_t len) { |
| 168 VLOG(1) << "OnHpackFragment: len=" << len |
| 169 << "; frame_header: " << frame_header; |
| 170 ASSERT_TRUE(got_start_callback); |
| 171 ASSERT_FALSE(got_end_callback); |
| 172 ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header)) << *this; |
| 173 ASSERT_TRUE( |
| 174 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); |
| 175 } |
| 176 |
| 177 void FrameParts::OnHeadersEnd() { |
| 178 VLOG(1) << "OnHeadersEnd; frame_header: " << frame_header; |
| 179 ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this; |
| 180 } |
| 181 |
| 182 void FrameParts::OnPriorityFrame(const Http2FrameHeader& header, |
| 183 const Http2PriorityFields& priority) { |
| 184 VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority; |
| 185 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this; |
| 186 ASSERT_FALSE(opt_priority); |
| 187 opt_priority = priority; |
| 188 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this; |
| 189 } |
| 190 |
| 191 void FrameParts::OnContinuationStart(const Http2FrameHeader& header) { |
| 192 VLOG(1) << "OnContinuationStart: " << header; |
| 193 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this; |
| 194 opt_payload_length = header.payload_length; |
| 195 } |
| 196 |
| 197 void FrameParts::OnContinuationEnd() { |
| 198 VLOG(1) << "OnContinuationEnd; frame_header: " << frame_header; |
| 199 ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this; |
| 200 } |
| 201 |
| 202 void FrameParts::OnPadLength(size_t trailing_length) { |
| 203 VLOG(1) << "OnPadLength: trailing_length=" << trailing_length; |
| 204 ASSERT_TRUE(InPaddedFrame()) << *this; |
| 205 ASSERT_FALSE(opt_pad_length); |
| 206 ASSERT_TRUE(opt_payload_length); |
| 207 size_t total_padding_length = trailing_length + 1; |
| 208 ASSERT_GE(opt_payload_length.value(), static_cast<int>(total_padding_length)); |
| 209 opt_payload_length = opt_payload_length.value() - total_padding_length; |
| 210 opt_pad_length = trailing_length; |
| 211 } |
| 212 |
| 213 void FrameParts::OnPadding(const char* pad, size_t skipped_length) { |
| 214 VLOG(1) << "OnPadding: skipped_length=" << skipped_length; |
| 215 ASSERT_TRUE(InPaddedFrame()) << *this; |
| 216 ASSERT_TRUE(opt_pad_length); |
| 217 ASSERT_TRUE(AppendString(StringPiece(pad, skipped_length), &padding, |
| 218 &opt_pad_length)); |
| 219 } |
| 220 |
| 221 void FrameParts::OnRstStream(const Http2FrameHeader& header, |
| 222 Http2ErrorCode error_code) { |
| 223 VLOG(1) << "OnRstStream: " << header << "; code=" << error_code; |
| 224 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this; |
| 225 ASSERT_FALSE(opt_rst_stream_error_code); |
| 226 opt_rst_stream_error_code = error_code; |
| 227 ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this; |
| 228 } |
| 229 |
| 230 void FrameParts::OnSettingsStart(const Http2FrameHeader& header) { |
| 231 VLOG(1) << "OnSettingsStart: " << header; |
| 232 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this; |
| 233 ASSERT_EQ(0u, settings.size()); |
| 234 ASSERT_FALSE(header.IsAck()) << header; |
| 235 } |
| 236 |
| 237 void FrameParts::OnSetting(const Http2SettingFields& setting_fields) { |
| 238 VLOG(1) << "OnSetting: " << setting_fields; |
| 239 ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this; |
| 240 settings.push_back(setting_fields); |
| 241 } |
| 242 |
| 243 void FrameParts::OnSettingsEnd() { |
| 244 VLOG(1) << "OnSettingsEnd; frame_header: " << frame_header; |
| 245 ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this; |
| 246 } |
| 247 |
| 248 void FrameParts::OnSettingsAck(const Http2FrameHeader& header) { |
| 249 VLOG(1) << "OnSettingsAck: " << header; |
| 250 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this; |
| 251 ASSERT_EQ(0u, settings.size()); |
| 252 ASSERT_TRUE(header.IsAck()); |
| 253 ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this; |
| 254 } |
| 255 |
| 256 void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header, |
| 257 const Http2PushPromiseFields& promise, |
| 258 size_t total_padding_length) { |
| 259 VLOG(1) << "OnPushPromiseStart header: " << header << "; promise: " << promise |
| 260 << "; total_padding_length: " << total_padding_length; |
| 261 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this; |
| 262 ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize()); |
| 263 opt_payload_length = |
| 264 header.payload_length - Http2PushPromiseFields::EncodedSize(); |
| 265 ASSERT_FALSE(opt_push_promise); |
| 266 opt_push_promise = promise; |
| 267 if (total_padding_length > 0) { |
| 268 ASSERT_GE(opt_payload_length.value(), |
| 269 static_cast<int>(total_padding_length)); |
| 270 OnPadLength(total_padding_length - 1); |
| 271 } else { |
| 272 ASSERT_FALSE(header.IsPadded()); |
| 273 } |
| 274 } |
| 275 |
| 276 void FrameParts::OnPushPromiseEnd() { |
| 277 VLOG(1) << "OnPushPromiseEnd; frame_header: " << frame_header; |
| 278 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this; |
| 279 } |
| 280 |
| 281 void FrameParts::OnPing(const Http2FrameHeader& header, |
| 282 const Http2PingFields& ping) { |
| 283 VLOG(1) << "OnPing header: " << header << " ping: " << ping; |
| 284 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this; |
| 285 ASSERT_FALSE(header.IsAck()); |
| 286 ASSERT_FALSE(opt_ping); |
| 287 opt_ping = ping; |
| 288 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this; |
| 289 } |
| 290 |
| 291 void FrameParts::OnPingAck(const Http2FrameHeader& header, |
| 292 const Http2PingFields& ping) { |
| 293 VLOG(1) << "OnPingAck header: " << header << " ping: " << ping; |
| 294 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this; |
| 295 ASSERT_TRUE(header.IsAck()); |
| 296 ASSERT_FALSE(opt_ping); |
| 297 opt_ping = ping; |
| 298 ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this; |
| 299 } |
| 300 |
| 301 void FrameParts::OnGoAwayStart(const Http2FrameHeader& header, |
| 302 const Http2GoAwayFields& goaway) { |
| 303 VLOG(1) << "OnGoAwayStart: " << goaway; |
| 304 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this; |
| 305 ASSERT_FALSE(opt_goaway); |
| 306 opt_goaway = goaway; |
| 307 opt_payload_length = header.payload_length - Http2GoAwayFields::EncodedSize(); |
| 308 } |
| 309 |
| 310 void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) { |
| 311 VLOG(1) << "OnGoAwayOpaqueData: len=" << len; |
| 312 ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this; |
| 313 ASSERT_TRUE( |
| 314 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); |
| 315 } |
| 316 |
| 317 void FrameParts::OnGoAwayEnd() { |
| 318 VLOG(1) << "OnGoAwayEnd; frame_header: " << frame_header; |
| 319 ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this; |
| 320 } |
| 321 |
| 322 void FrameParts::OnWindowUpdate(const Http2FrameHeader& header, |
| 323 uint32_t increment) { |
| 324 VLOG(1) << "OnWindowUpdate header: " << header |
| 325 << " increment=" << increment; |
| 326 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this; |
| 327 ASSERT_FALSE(opt_window_update_increment); |
| 328 opt_window_update_increment = increment; |
| 329 ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this; |
| 330 } |
| 331 |
| 332 void FrameParts::OnAltSvcStart(const Http2FrameHeader& header, |
| 333 size_t origin_length, |
| 334 size_t value_length) { |
| 335 VLOG(1) << "OnAltSvcStart: " << header |
| 336 << " origin_length: " << origin_length |
| 337 << " value_length: " << value_length; |
| 338 ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this; |
| 339 ASSERT_FALSE(opt_altsvc_origin_length); |
| 340 opt_altsvc_origin_length = origin_length; |
| 341 ASSERT_FALSE(opt_altsvc_value_length); |
| 342 opt_altsvc_value_length = value_length; |
| 343 } |
| 344 |
| 345 void FrameParts::OnAltSvcOriginData(const char* data, size_t len) { |
| 346 VLOG(1) << "OnAltSvcOriginData: len=" << len; |
| 347 ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; |
| 348 ASSERT_TRUE(AppendString(StringPiece(data, len), &altsvc_origin, |
| 349 &opt_altsvc_origin_length)); |
| 350 } |
| 351 |
| 352 void FrameParts::OnAltSvcValueData(const char* data, size_t len) { |
| 353 VLOG(1) << "OnAltSvcValueData: len=" << len; |
| 354 ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this; |
| 355 ASSERT_TRUE(AppendString(StringPiece(data, len), &altsvc_value, |
| 356 &opt_altsvc_value_length)); |
| 357 } |
| 358 |
| 359 void FrameParts::OnAltSvcEnd() { |
| 360 VLOG(1) << "OnAltSvcEnd; frame_header: " << frame_header; |
| 361 ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this; |
| 362 } |
| 363 |
| 364 void FrameParts::OnUnknownStart(const Http2FrameHeader& header) { |
| 365 VLOG(1) << "OnUnknownStart: " << header; |
| 366 ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header; |
| 367 ASSERT_FALSE(got_start_callback); |
| 368 ASSERT_EQ(frame_header, header); |
| 369 got_start_callback = true; |
| 370 opt_payload_length = header.payload_length; |
| 371 } |
| 372 |
| 373 void FrameParts::OnUnknownPayload(const char* data, size_t len) { |
| 374 VLOG(1) << "OnUnknownPayload: len=" << len; |
| 375 ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this; |
| 376 ASSERT_TRUE(got_start_callback); |
| 377 ASSERT_FALSE(got_end_callback); |
| 378 ASSERT_TRUE( |
| 379 AppendString(StringPiece(data, len), &payload, &opt_payload_length)); |
| 380 } |
| 381 |
| 382 void FrameParts::OnUnknownEnd() { |
| 383 VLOG(1) << "OnUnknownEnd; frame_header: " << frame_header; |
| 384 ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header.type)) << *this; |
| 385 ASSERT_TRUE(got_start_callback); |
| 386 ASSERT_FALSE(got_end_callback); |
| 387 got_end_callback = true; |
| 388 } |
| 389 |
| 390 void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header, |
| 391 size_t missing_length) { |
| 392 VLOG(1) << "OnPaddingTooLong: " << header |
| 393 << "; missing_length: " << missing_length; |
| 394 ASSERT_EQ(frame_header, header); |
| 395 ASSERT_FALSE(got_end_callback); |
| 396 ASSERT_TRUE(FrameIsPadded(header)); |
| 397 ASSERT_FALSE(opt_pad_length); |
| 398 ASSERT_FALSE(opt_missing_length); |
| 399 opt_missing_length = missing_length; |
| 400 got_start_callback = true; |
| 401 got_end_callback = true; |
| 402 } |
| 403 |
| 404 void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) { |
| 405 VLOG(1) << "OnFrameSizeError: " << header; |
| 406 ASSERT_EQ(frame_header, header); |
| 407 ASSERT_FALSE(got_end_callback); |
| 408 ASSERT_FALSE(has_frame_size_error); |
| 409 has_frame_size_error = true; |
| 410 got_end_callback = true; |
| 411 } |
| 412 |
| 413 void FrameParts::OutputTo(std::ostream& out) const { |
| 414 out << "FrameParts{\n frame_header: " << frame_header << "\n"; |
| 415 if (!payload.empty()) { |
| 416 out << " payload=\"" << EscapeQueryParamValue(payload, false) << "\"\n"; |
| 417 } |
| 418 if (!padding.empty()) { |
| 419 out << " padding=\"" << EscapeQueryParamValue(padding, false) << "\"\n"; |
| 420 } |
| 421 if (!altsvc_origin.empty()) { |
| 422 out << " altsvc_origin=\"" << EscapeQueryParamValue(altsvc_origin, false) |
| 423 << "\"\n"; |
| 424 } |
| 425 if (!altsvc_value.empty()) { |
| 426 out << " altsvc_value=\"" << EscapeQueryParamValue(altsvc_value, false) |
| 427 << "\"\n"; |
| 428 } |
| 429 if (opt_priority) { |
| 430 out << " priority=" << opt_priority.value() << "\n"; |
| 431 } |
| 432 if (opt_rst_stream_error_code) { |
| 433 out << " rst_stream=" << opt_rst_stream_error_code.value() << "\n"; |
| 434 } |
| 435 if (opt_push_promise) { |
| 436 out << " push_promise=" << opt_push_promise.value() << "\n"; |
| 437 } |
| 438 if (opt_ping) { |
| 439 out << " ping=" << opt_ping.value() << "\n"; |
| 440 } |
| 441 if (opt_goaway) { |
| 442 out << " goaway=" << opt_goaway.value() << "\n"; |
| 443 } |
| 444 if (opt_window_update_increment) { |
| 445 out << " window_update=" << opt_window_update_increment.value() << "\n"; |
| 446 } |
| 447 if (opt_payload_length) { |
| 448 out << " payload_length=" << opt_payload_length.value() << "\n"; |
| 449 } |
| 450 if (opt_pad_length) { |
| 451 out << " pad_length=" << opt_pad_length.value() << "\n"; |
| 452 } |
| 453 if (opt_missing_length) { |
| 454 out << " missing_length=" << opt_missing_length.value() << "\n"; |
| 455 } |
| 456 if (opt_altsvc_origin_length) { |
| 457 out << " origin_length=" << opt_altsvc_origin_length.value() << "\n"; |
| 458 } |
| 459 if (opt_altsvc_value_length) { |
| 460 out << " value_length=" << opt_altsvc_value_length.value() << "\n"; |
| 461 } |
| 462 if (has_frame_size_error) { |
| 463 out << " has_frame_size_error\n"; |
| 464 } |
| 465 if (got_start_callback) { |
| 466 out << " got_start_callback\n"; |
| 467 } |
| 468 if (got_end_callback) { |
| 469 out << " got_end_callback\n"; |
| 470 } |
| 471 for (size_t ndx = 0; ndx < settings.size(); ++ndx) { |
| 472 out << " setting[" << ndx << "]=" << settings[ndx]; |
| 473 } |
| 474 out << "}"; |
| 475 } |
| 476 |
| 477 AssertionResult FrameParts::StartFrameOfType( |
| 478 const Http2FrameHeader& header, |
| 479 Http2FrameType expected_frame_type) { |
| 480 VERIFY_EQ(header.type, expected_frame_type); |
| 481 VERIFY_FALSE(got_start_callback); |
| 482 VERIFY_FALSE(got_end_callback); |
| 483 VERIFY_EQ(frame_header, header); |
| 484 got_start_callback = true; |
| 485 return AssertionSuccess(); |
| 486 } |
| 487 |
| 488 AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) { |
| 489 VERIFY_TRUE(got_start_callback); |
| 490 VERIFY_FALSE(got_end_callback); |
| 491 VERIFY_EQ(frame_header.type, expected_frame_type); |
| 492 return AssertionSuccess(); |
| 493 } |
| 494 |
| 495 AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) { |
| 496 VERIFY_SUCCESS(InFrameOfType(expected_frame_type)); |
| 497 got_end_callback = true; |
| 498 return AssertionSuccess(); |
| 499 } |
| 500 |
| 501 AssertionResult FrameParts::InPaddedFrame() { |
| 502 VERIFY_TRUE(got_start_callback); |
| 503 VERIFY_FALSE(got_end_callback); |
| 504 VERIFY_TRUE(FrameIsPadded(frame_header)); |
| 505 return AssertionSuccess(); |
| 506 } |
| 507 |
| 508 AssertionResult FrameParts::AppendString(StringPiece source, |
| 509 string* target, |
| 510 base::Optional<int>* opt_length) { |
| 511 source.AppendToString(target); |
| 512 if (opt_length != nullptr) { |
| 513 VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this; |
| 514 VERIFY_LE(target->size(), static_cast<size_t>(opt_length->value())) |
| 515 << "String too large; source.size() = " << source.size() << "\n" |
| 516 << *this; |
| 517 } |
| 518 return ::testing::AssertionSuccess(); |
| 519 } |
| 520 |
| 521 std::ostream& operator<<(std::ostream& out, const FrameParts& v) { |
| 522 v.OutputTo(out); |
| 523 return out; |
| 524 } |
| 525 |
| 526 } // namespace test |
| 527 } // namespace net |
OLD | NEW |