| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "quiche/http2/test_tools/frame_parts_collector.h" |
| |
| #include <utility> |
| |
| #include "quiche/http2/test_tools/http2_structures_test_util.h" |
| #include "quiche/common/platform/api/quiche_logging.h" |
| #include "quiche/common/platform/api/quiche_test.h" |
| |
| namespace http2 { |
| namespace test { |
| |
| FramePartsCollector::FramePartsCollector() = default; |
| FramePartsCollector::~FramePartsCollector() = default; |
| |
| void FramePartsCollector::Reset() { |
| current_frame_.reset(); |
| collected_frames_.clear(); |
| expected_header_set_ = false; |
| } |
| |
| const FrameParts* FramePartsCollector::frame(size_t n) const { |
| if (n < size()) { |
| return collected_frames_.at(n).get(); |
| } |
| QUICHE_CHECK(n == size()); |
| return current_frame(); |
| } |
| |
| void FramePartsCollector::ExpectFrameHeader(const Http2FrameHeader& header) { |
| EXPECT_FALSE(IsInProgress()); |
| EXPECT_FALSE(expected_header_set_) |
| << "expected_header_: " << expected_header_; |
| expected_header_ = header; |
| expected_header_set_ = true; |
| // OnFrameHeader is called before the flags are scrubbed, but the other |
| // methods are called after, so scrub the invalid flags from expected_header_. |
| ScrubFlagsOfHeader(&expected_header_); |
| } |
| |
| void FramePartsCollector::TestExpectedHeader(const Http2FrameHeader& header) { |
| if (expected_header_set_) { |
| EXPECT_EQ(header, expected_header_); |
| expected_header_set_ = false; |
| } |
| } |
| |
| Http2FrameDecoderListener* FramePartsCollector::StartFrame( |
| const Http2FrameHeader& header) { |
| TestExpectedHeader(header); |
| EXPECT_FALSE(IsInProgress()); |
| if (current_frame_ == nullptr) { |
| current_frame_ = std::make_unique<FrameParts>(header); |
| } |
| return current_frame(); |
| } |
| |
| Http2FrameDecoderListener* FramePartsCollector::StartAndEndFrame( |
| const Http2FrameHeader& header) { |
| TestExpectedHeader(header); |
| EXPECT_FALSE(IsInProgress()); |
| if (current_frame_ == nullptr) { |
| current_frame_ = std::make_unique<FrameParts>(header); |
| } |
| Http2FrameDecoderListener* result = current_frame(); |
| collected_frames_.push_back(std::move(current_frame_)); |
| return result; |
| } |
| |
| Http2FrameDecoderListener* FramePartsCollector::CurrentFrame() { |
| EXPECT_TRUE(IsInProgress()); |
| if (current_frame_ == nullptr) { |
| return &failing_listener_; |
| } |
| return current_frame(); |
| } |
| |
| Http2FrameDecoderListener* FramePartsCollector::EndFrame() { |
| EXPECT_TRUE(IsInProgress()); |
| if (current_frame_ == nullptr) { |
| return &failing_listener_; |
| } |
| Http2FrameDecoderListener* result = current_frame(); |
| collected_frames_.push_back(std::move(current_frame_)); |
| return result; |
| } |
| |
| Http2FrameDecoderListener* FramePartsCollector::FrameError( |
| const Http2FrameHeader& header) { |
| TestExpectedHeader(header); |
| if (current_frame_ == nullptr) { |
| // The decoder may detect an error before making any calls to the listener |
| // regarding the frame, in which case current_frame_==nullptr and we need |
| // to create a FrameParts instance. |
| current_frame_ = std::make_unique<FrameParts>(header); |
| } else { |
| // Similarly, the decoder may have made calls to the listener regarding the |
| // frame before detecting the error; for example, the DATA payload decoder |
| // calls OnDataStart before it can detect padding errors, hence before it |
| // can call OnPaddingTooLong. |
| EXPECT_EQ(header, current_frame_->GetFrameHeader()); |
| } |
| Http2FrameDecoderListener* result = current_frame(); |
| collected_frames_.push_back(std::move(current_frame_)); |
| return result; |
| } |
| |
| } // namespace test |
| } // namespace http2 |