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 "quiche/http2/test_tools/frame_parts_collector.h" 6 7 #include <utility> 8 9 #include "quiche/http2/test_tools/http2_structures_test_util.h" 10 #include "quiche/common/platform/api/quiche_logging.h" 11 #include "quiche/common/platform/api/quiche_test.h" 12 13 namespace http2 { 14 namespace test { 15 16 FramePartsCollector::FramePartsCollector() = default; 17 FramePartsCollector::~FramePartsCollector() = default; 18 Reset()19void FramePartsCollector::Reset() { 20 current_frame_.reset(); 21 collected_frames_.clear(); 22 expected_header_set_ = false; 23 } 24 frame(size_t n) const25const FrameParts* FramePartsCollector::frame(size_t n) const { 26 if (n < size()) { 27 return collected_frames_.at(n).get(); 28 } 29 QUICHE_CHECK(n == size()); 30 return current_frame(); 31 } 32 ExpectFrameHeader(const Http2FrameHeader & header)33void FramePartsCollector::ExpectFrameHeader(const Http2FrameHeader& header) { 34 EXPECT_FALSE(IsInProgress()); 35 EXPECT_FALSE(expected_header_set_) 36 << "expected_header_: " << expected_header_; 37 expected_header_ = header; 38 expected_header_set_ = true; 39 // OnFrameHeader is called before the flags are scrubbed, but the other 40 // methods are called after, so scrub the invalid flags from expected_header_. 41 ScrubFlagsOfHeader(&expected_header_); 42 } 43 TestExpectedHeader(const Http2FrameHeader & header)44void FramePartsCollector::TestExpectedHeader(const Http2FrameHeader& header) { 45 if (expected_header_set_) { 46 EXPECT_EQ(header, expected_header_); 47 expected_header_set_ = false; 48 } 49 } 50 StartFrame(const Http2FrameHeader & header)51Http2FrameDecoderListener* FramePartsCollector::StartFrame( 52 const Http2FrameHeader& header) { 53 TestExpectedHeader(header); 54 EXPECT_FALSE(IsInProgress()); 55 if (current_frame_ == nullptr) { 56 current_frame_ = std::make_unique<FrameParts>(header); 57 } 58 return current_frame(); 59 } 60 StartAndEndFrame(const Http2FrameHeader & header)61Http2FrameDecoderListener* FramePartsCollector::StartAndEndFrame( 62 const Http2FrameHeader& header) { 63 TestExpectedHeader(header); 64 EXPECT_FALSE(IsInProgress()); 65 if (current_frame_ == nullptr) { 66 current_frame_ = std::make_unique<FrameParts>(header); 67 } 68 Http2FrameDecoderListener* result = current_frame(); 69 collected_frames_.push_back(std::move(current_frame_)); 70 return result; 71 } 72 CurrentFrame()73Http2FrameDecoderListener* FramePartsCollector::CurrentFrame() { 74 EXPECT_TRUE(IsInProgress()); 75 if (current_frame_ == nullptr) { 76 return &failing_listener_; 77 } 78 return current_frame(); 79 } 80 EndFrame()81Http2FrameDecoderListener* FramePartsCollector::EndFrame() { 82 EXPECT_TRUE(IsInProgress()); 83 if (current_frame_ == nullptr) { 84 return &failing_listener_; 85 } 86 Http2FrameDecoderListener* result = current_frame(); 87 collected_frames_.push_back(std::move(current_frame_)); 88 return result; 89 } 90 FrameError(const Http2FrameHeader & header)91Http2FrameDecoderListener* FramePartsCollector::FrameError( 92 const Http2FrameHeader& header) { 93 TestExpectedHeader(header); 94 if (current_frame_ == nullptr) { 95 // The decoder may detect an error before making any calls to the listener 96 // regarding the frame, in which case current_frame_==nullptr and we need 97 // to create a FrameParts instance. 98 current_frame_ = std::make_unique<FrameParts>(header); 99 } else { 100 // Similarly, the decoder may have made calls to the listener regarding the 101 // frame before detecting the error; for example, the DATA payload decoder 102 // calls OnDataStart before it can detect padding errors, hence before it 103 // can call OnPaddingTooLong. 104 EXPECT_EQ(header, current_frame_->GetFrameHeader()); 105 } 106 Http2FrameDecoderListener* result = current_frame(); 107 collected_frames_.push_back(std::move(current_frame_)); 108 return result; 109 } 110 111 } // namespace test 112 } // namespace http2 113