Remove SpdyDeframerVisitor.
PiperOrigin-RevId: 342158952
Change-Id: I12145c852b8fae38a9baf53037829da3cc337a19
diff --git a/spdy/core/spdy_deframer_visitor.cc b/spdy/core/spdy_deframer_visitor.cc
deleted file mode 100644
index 835fea9..0000000
--- a/spdy/core/spdy_deframer_visitor.cc
+++ /dev/null
@@ -1,1031 +0,0 @@
-// 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 "net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h"
-
-#include <stdlib.h>
-
-#include <algorithm>
-#include <cstdint>
-#include <limits>
-#include <memory>
-
-#include "absl/strings/string_view.h"
-#include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
-#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
-#include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
-#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_flags.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-using ::testing::AssertionFailure;
-using ::testing::AssertionResult;
-using ::testing::AssertionSuccess;
-
-namespace spdy {
-namespace test {
-
-// Specify whether to process headers as request or response in visitor-related
-// params.
-enum class HeaderDirection { REQUEST, RESPONSE };
-
-// Types of HTTP/2 frames, per RFC 7540.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-enum Http2FrameType {
- DATA = 0,
- HEADERS = 1,
- PRIORITY = 2,
- RST_STREAM = 3,
- SETTINGS = 4,
- PUSH_PROMISE = 5,
- PING = 6,
- GOAWAY = 7,
- WINDOW_UPDATE = 8,
- CONTINUATION = 9,
- ALTSVC = 10,
-
- // Not a frame type.
- UNSET = -1,
- UNKNOWN = -2,
-};
-
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-const char* Http2FrameTypeToString(Http2FrameType v) {
- switch (v) {
- case DATA:
- return "DATA";
- case HEADERS:
- return "HEADERS";
- case PRIORITY:
- return "PRIORITY";
- case RST_STREAM:
- return "RST_STREAM";
- case SETTINGS:
- return "SETTINGS";
- case PUSH_PROMISE:
- return "PUSH_PROMISE";
- case PING:
- return "PING";
- case GOAWAY:
- return "GOAWAY";
- case WINDOW_UPDATE:
- return "WINDOW_UPDATE";
- case CONTINUATION:
- return "CONTINUATION";
- case ALTSVC:
- return "ALTSVC";
- case UNSET:
- return "UNSET";
- case UNKNOWN:
- return "UNKNOWN";
- default:
- return "Invalid Http2FrameType";
- }
-}
-
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-inline std::ostream& operator<<(std::ostream& out, Http2FrameType v) {
- return out << Http2FrameTypeToString(v);
-}
-
-// Flag bits in the flag field of the common header of HTTP/2 frames
-// (see https://httpwg.github.io/specs/rfc7540.html#FrameHeader for details on
-// the fixed 9-octet header structure shared by all frames).
-// Flag bits are only valid for specified frame types.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-enum Http2HeaderFlag {
- NO_FLAGS = 0,
-
- END_STREAM_FLAG = 0x1,
- ACK_FLAG = 0x1,
- END_HEADERS_FLAG = 0x4,
- PADDED_FLAG = 0x8,
- PRIORITY_FLAG = 0x20,
-};
-
-// Returns name of frame type.
-// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
-const char* Http2FrameTypeToString(Http2FrameType v);
-
-void SpdyDeframerVisitorInterface::OnPingAck(
- std::unique_ptr<SpdyPingIR> frame) {
- OnPing(std::move(frame));
-}
-
-void SpdyDeframerVisitorInterface::OnSettingsAck(
- std::unique_ptr<SpdySettingsIR> frame) {
- OnSettings(std::move(frame), nullptr);
-}
-
-class SpdyTestDeframerImpl : public SpdyTestDeframer,
- public SpdyHeadersHandlerInterface {
- public:
- explicit SpdyTestDeframerImpl(
- std::unique_ptr<SpdyDeframerVisitorInterface> listener)
- : listener_(std::move(listener)) {
- CHECK(listener_ != nullptr);
- }
- SpdyTestDeframerImpl(const SpdyTestDeframerImpl&) = delete;
- SpdyTestDeframerImpl& operator=(const SpdyTestDeframerImpl&) = delete;
- ~SpdyTestDeframerImpl() override = default;
-
- bool AtFrameEnd() override;
-
- // Callbacks defined in SpdyFramerVisitorInterface. These are in the
- // alphabetical order for ease of navigation, and are not in same order
- // as in SpdyFramerVisitorInterface.
- void OnAltSvc(SpdyStreamId stream_id,
- absl::string_view origin,
- const SpdyAltSvcWireFormat::AlternativeServiceVector&
- altsvc_vector) override;
- void OnContinuation(SpdyStreamId stream_id, bool end) override;
- SpdyHeadersHandlerInterface* OnHeaderFrameStart(
- SpdyStreamId stream_id) override;
- void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
- void OnDataFrameHeader(SpdyStreamId stream_id,
- size_t length,
- bool fin) override;
- void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
- std::string detailed_error) override;
- void OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyErrorCode error_code) override;
- bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
- void OnHeaders(SpdyStreamId stream_id,
- bool has_priority,
- int weight,
- SpdyStreamId parent_stream_id,
- bool exclusive,
- bool fin,
- bool end) override;
- void OnPing(SpdyPingId unique_id, bool is_ack) override;
- void OnPriority(SpdyStreamId stream_id,
- SpdyStreamId parent_stream_id,
- int weight,
- bool exclusive) override;
- void OnPushPromise(SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id,
- bool end) override;
- void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
- void OnSetting(SpdySettingsId id, uint32_t value) override;
- void OnSettings() override;
- void OnSettingsAck() override;
- void OnSettingsEnd() override;
- void OnStreamFrameData(SpdyStreamId stream_id,
- const char* data,
- size_t len) override;
- void OnStreamEnd(SpdyStreamId stream_id) override;
- void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
- void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
- bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
- void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;
-
- // Callbacks defined in SpdyHeadersHandlerInterface.
-
- void OnHeaderBlockStart() override;
- void OnHeader(absl::string_view key, absl::string_view value) override;
- void OnHeaderBlockEnd(size_t header_bytes_parsed,
- size_t compressed_header_bytes_parsed) override;
-
- protected:
- void AtDataEnd();
- void AtGoAwayEnd();
- void AtHeadersEnd();
- void AtPushPromiseEnd();
-
- // Per-physical frame state.
- // Frame type of the frame currently being processed.
- Http2FrameType frame_type_ = UNSET;
- // Stream id of the frame currently being processed.
- SpdyStreamId stream_id_;
- // Did the most recent frame header include the END_HEADERS flag?
- bool end_ = false;
- // Did the most recent frame header include the ack flag?
- bool ack_ = false;
-
- // Per-HPACK block state. Only valid while processing a HEADERS or
- // PUSH_PROMISE frame, and its CONTINUATION frames.
- // Did the most recent HEADERS or PUSH_PROMISE include the END_STREAM flag?
- // Note that this does not necessarily indicate that the current frame is
- // the last frame for the stream (may be followed by CONTINUATION frames,
- // may only half close).
- bool fin_ = false;
- bool got_hpack_end_ = false;
-
- std::unique_ptr<std::string> data_;
-
- // Total length of the data frame.
- size_t data_len_ = 0;
-
- // Amount of skipped padding (i.e. total length of padding, including Pad
- // Length field).
- size_t padding_len_ = 0;
-
- std::unique_ptr<std::string> goaway_description_;
- std::unique_ptr<StringPairVector> headers_;
- std::unique_ptr<SettingVector> settings_;
- std::unique_ptr<RecordingHeadersHandler> headers_handler_;
-
- std::unique_ptr<SpdyGoAwayIR> goaway_ir_;
- std::unique_ptr<SpdyHeadersIR> headers_ir_;
- std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_;
- std::unique_ptr<SpdySettingsIR> settings_ir_;
-
- private:
- std::unique_ptr<SpdyDeframerVisitorInterface> listener_;
-};
-
-// static
-std::unique_ptr<SpdyTestDeframer> SpdyTestDeframer::CreateConverter(
- std::unique_ptr<SpdyDeframerVisitorInterface> listener) {
- return std::make_unique<SpdyTestDeframerImpl>(std::move(listener));
-}
-
-void SpdyTestDeframerImpl::AtDataEnd() {
- SPDY_DVLOG(1) << "AtDataEnd";
- CHECK_EQ(data_len_, padding_len_ + data_->size());
- auto ptr = std::make_unique<SpdyDataIR>(stream_id_, std::move(*data_));
- CHECK_EQ(0u, data_->size());
- data_.reset();
-
- CHECK_LE(0u, padding_len_);
- CHECK_LE(padding_len_, 256u);
- if (padding_len_ > 0) {
- ptr->set_padding_len(padding_len_);
- }
- padding_len_ = 0;
-
- ptr->set_fin(fin_);
- listener_->OnData(std::move(ptr));
- frame_type_ = UNSET;
- fin_ = false;
- data_len_ = 0;
-}
-
-void SpdyTestDeframerImpl::AtGoAwayEnd() {
- SPDY_DVLOG(1) << "AtDataEnd";
- CHECK_EQ(frame_type_, GOAWAY);
- if (HTTP2_DIE_IF_NULL(goaway_description_)->empty()) {
- listener_->OnGoAway(std::move(goaway_ir_));
- } else {
- listener_->OnGoAway(std::make_unique<SpdyGoAwayIR>(
- goaway_ir_->last_good_stream_id(), goaway_ir_->error_code(),
- std::move(*goaway_description_)));
- CHECK_EQ(0u, goaway_description_->size());
- }
- goaway_description_.reset();
- goaway_ir_.reset();
- frame_type_ = UNSET;
-}
-
-void SpdyTestDeframerImpl::AtHeadersEnd() {
- SPDY_DVLOG(1) << "AtDataEnd";
- CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(end_) << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(got_hpack_end_);
-
- CHECK(headers_ir_ != nullptr);
- CHECK(headers_ != nullptr);
- CHECK(headers_handler_ != nullptr);
-
- CHECK_LE(0u, padding_len_);
- CHECK_LE(padding_len_, 256u);
- if (padding_len_ > 0) {
- headers_ir_->set_padding_len(padding_len_);
- }
- padding_len_ = 0;
-
- headers_ir_->set_header_block(headers_handler_->decoded_block().Clone());
- headers_handler_.reset();
- listener_->OnHeaders(std::move(headers_ir_), std::move(headers_));
-
- frame_type_ = UNSET;
- fin_ = false;
- end_ = false;
- got_hpack_end_ = false;
-}
-
-void SpdyTestDeframerImpl::AtPushPromiseEnd() {
- SPDY_DVLOG(1) << "AtDataEnd";
- CHECK(frame_type_ == PUSH_PROMISE || frame_type_ == CONTINUATION)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(end_) << " frame_type_=" << Http2FrameTypeToString(frame_type_);
-
- CHECK(push_promise_ir_ != nullptr);
- CHECK(headers_ != nullptr);
- CHECK(headers_handler_ != nullptr);
-
- CHECK_EQ(headers_ir_.get(), nullptr);
-
- CHECK_LE(0u, padding_len_);
- CHECK_LE(padding_len_, 256u);
- if (padding_len_ > 0) {
- push_promise_ir_->set_padding_len(padding_len_);
- }
- padding_len_ = 0;
-
- push_promise_ir_->set_header_block(headers_handler_->decoded_block().Clone());
- headers_handler_.reset();
- listener_->OnPushPromise(std::move(push_promise_ir_), std::move(headers_));
-
- frame_type_ = UNSET;
- end_ = false;
-}
-
-bool SpdyTestDeframerImpl::AtFrameEnd() {
- bool incomplete_logical_header = false;
- // The caller says that the SpdyFrame has reached the end of the frame,
- // so if we have any accumulated data, flush it.
- switch (frame_type_) {
- case DATA:
- AtDataEnd();
- break;
-
- case GOAWAY:
- AtGoAwayEnd();
- break;
-
- case HEADERS:
- if (end_) {
- AtHeadersEnd();
- } else {
- incomplete_logical_header = true;
- }
- break;
-
- case PUSH_PROMISE:
- if (end_) {
- AtPushPromiseEnd();
- } else {
- incomplete_logical_header = true;
- }
- break;
-
- case CONTINUATION:
- if (end_) {
- if (headers_ir_) {
- AtHeadersEnd();
- } else if (push_promise_ir_) {
- AtPushPromiseEnd();
- } else {
- SPDY_LOG(FATAL) << "Where is the SpdyFrameIR for the headers!";
- }
- } else {
- incomplete_logical_header = true;
- }
- break;
-
- case UNSET:
- // Except for the frame types above, the others don't leave any record
- // in the state of this object. Make sure nothing got left by accident.
- CHECK_EQ(data_.get(), nullptr);
- CHECK_EQ(goaway_description_.get(), nullptr);
- CHECK_EQ(goaway_ir_.get(), nullptr);
- CHECK_EQ(headers_.get(), nullptr);
- CHECK_EQ(headers_handler_.get(), nullptr);
- CHECK_EQ(headers_ir_.get(), nullptr);
- CHECK_EQ(push_promise_ir_.get(), nullptr);
- CHECK_EQ(settings_.get(), nullptr);
- CHECK_EQ(settings_ir_.get(), nullptr);
- break;
-
- default:
- SPDY_BUG << "Expected UNSET, instead frame_type_==" << frame_type_;
- return false;
- }
- frame_type_ = UNSET;
- stream_id_ = 0;
- end_ = false;
- ack_ = false;
- if (!incomplete_logical_header) {
- fin_ = false;
- }
- return true;
-}
-
-// Overridden methods from SpdyFramerVisitorInterface in alpha order...
-
-void SpdyTestDeframerImpl::OnAltSvc(
- SpdyStreamId stream_id,
- absl::string_view origin,
- const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
- SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
- auto ptr = std::make_unique<SpdyAltSvcIR>(stream_id);
- ptr->set_origin(std::string(origin));
- for (auto& altsvc : altsvc_vector) {
- ptr->add_altsvc(altsvc);
- }
- listener_->OnAltSvc(std::move(ptr));
-}
-
-// A CONTINUATION frame contains a Header Block Fragment, and immediately
-// follows another frame that contains a Header Block Fragment (HEADERS,
-// PUSH_PROMISE or CONTINUATION). The last such frame has the END flag set.
-// SpdyFramer ensures that the behavior is correct before calling the visitor.
-void SpdyTestDeframerImpl::OnContinuation(SpdyStreamId stream_id, bool end) {
- SPDY_DVLOG(1) << "OnContinuation stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
- CHECK_NE(nullptr, headers_.get());
- frame_type_ = CONTINUATION;
-
- stream_id_ = stream_id;
- end_ = end;
-}
-
-// Note that length includes the padding length (0 to 256, when the optional
-// padding length field is counted). Padding comes after the payload, both
-// for DATA frames and for control frames.
-void SpdyTestDeframerImpl::OnDataFrameHeader(SpdyStreamId stream_id,
- size_t length,
- bool fin) {
- SPDY_DVLOG(1) << "OnDataFrameHeader stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
- CHECK_EQ(data_.get(), nullptr);
- frame_type_ = DATA;
-
- stream_id_ = stream_id;
- fin_ = fin;
- data_len_ = length;
- data_ = std::make_unique<std::string>();
-}
-
-// The SpdyFramer will not process any more data at this point.
-void SpdyTestDeframerImpl::OnError(
- http2::Http2DecoderAdapter::SpdyFramerError error,
- std::string /*detailed_error*/) {
- SPDY_DVLOG(1) << "SpdyFramer detected an error in the stream: "
- << http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)
- << " frame_type_: " << Http2FrameTypeToString(frame_type_);
- listener_->OnError(error, this);
-}
-
-// Received a GOAWAY frame from the peer. The last stream id it accepted from us
-// is |last_accepted_stream_id|. |status| is a protocol defined error code.
-// The frame may also contain data. After this OnGoAwayFrameData will be called
-// for any non-zero amount of data, and after that it will be called with len==0
-// to indicate the end of the GOAWAY frame.
-void SpdyTestDeframerImpl::OnGoAway(SpdyStreamId last_accepted_stream_id,
- SpdyErrorCode error_code) {
- SPDY_DVLOG(1) << "OnGoAway last_accepted_stream_id: "
- << last_accepted_stream_id << " error code: " << error_code;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- frame_type_ = GOAWAY;
- goaway_ir_ =
- std::make_unique<SpdyGoAwayIR>(last_accepted_stream_id, error_code, "");
- goaway_description_ = std::make_unique<std::string>();
-}
-
-// If len==0 then we've reached the end of the GOAWAY frame.
-bool SpdyTestDeframerImpl::OnGoAwayFrameData(const char* goaway_data,
- size_t len) {
- SPDY_DVLOG(1) << "OnGoAwayFrameData";
- CHECK_EQ(frame_type_, GOAWAY)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(goaway_description_ != nullptr);
- goaway_description_->append(goaway_data, len);
- return true;
-}
-
-SpdyHeadersHandlerInterface* SpdyTestDeframerImpl::OnHeaderFrameStart(
- SpdyStreamId /*stream_id*/) {
- return this;
-}
-
-void SpdyTestDeframerImpl::OnHeaderFrameEnd(SpdyStreamId stream_id) {
- SPDY_DVLOG(1) << "OnHeaderFrameEnd stream_id: " << stream_id;
-}
-
-// Received the fixed portion of a HEADERS frame. Called before the variable
-// length (including zero length) Header Block Fragment is processed. If fin
-// is true then there will be no DATA or trailing HEADERS after this HEADERS
-// frame.
-// If end is true, then there will be no CONTINUATION frame(s) following this
-// frame; else if true then there will be CONTINATION frames(s) immediately
-// following this frame, terminated by a CONTINUATION frame with end==true.
-void SpdyTestDeframerImpl::OnHeaders(SpdyStreamId stream_id,
- bool has_priority,
- int weight,
- SpdyStreamId parent_stream_id,
- bool exclusive,
- bool fin,
- bool end) {
- SPDY_DVLOG(1) << "OnHeaders stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
- frame_type_ = HEADERS;
-
- stream_id_ = stream_id;
- fin_ = fin;
- end_ = end;
-
- headers_ = std::make_unique<StringPairVector>();
- headers_handler_ = std::make_unique<RecordingHeadersHandler>();
- headers_ir_ = std::make_unique<SpdyHeadersIR>(stream_id);
- headers_ir_->set_fin(fin);
- if (has_priority) {
- headers_ir_->set_has_priority(true);
- headers_ir_->set_weight(weight);
- headers_ir_->set_parent_stream_id(parent_stream_id);
- headers_ir_->set_exclusive(exclusive);
- }
-}
-
-// The HTTP/2 protocol refers to the payload, |unique_id| here, as 8 octets of
-// opaque data that is to be echoed back to the sender, with the ACK bit added.
-// It isn't defined as a counter,
-// or frame id, as the SpdyPingId naming might imply.
-// Responding to a PING is supposed to be at the highest priority.
-void SpdyTestDeframerImpl::OnPing(uint64_t unique_id, bool is_ack) {
- SPDY_DVLOG(1) << "OnPing unique_id: " << unique_id
- << " is_ack: " << (is_ack ? "true" : "false");
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- auto ptr = std::make_unique<SpdyPingIR>(unique_id);
- if (is_ack) {
- ptr->set_is_ack(is_ack);
- listener_->OnPingAck(std::move(ptr));
- } else {
- listener_->OnPing(std::move(ptr));
- }
-}
-
-void SpdyTestDeframerImpl::OnPriority(SpdyStreamId stream_id,
- SpdyStreamId parent_stream_id,
- int weight,
- bool exclusive) {
- SPDY_DVLOG(1) << "OnPriority stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
-
- listener_->OnPriority(std::make_unique<SpdyPriorityIR>(
- stream_id, parent_stream_id, weight, exclusive));
-}
-
-void SpdyTestDeframerImpl::OnPushPromise(SpdyStreamId stream_id,
- SpdyStreamId promised_stream_id,
- bool end) {
- SPDY_DVLOG(1) << "OnPushPromise stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
-
- frame_type_ = PUSH_PROMISE;
- stream_id_ = stream_id;
- end_ = end;
-
- headers_ = std::make_unique<StringPairVector>();
- headers_handler_ = std::make_unique<RecordingHeadersHandler>();
- push_promise_ir_ =
- std::make_unique<SpdyPushPromiseIR>(stream_id, promised_stream_id);
-}
-
-// Closes the specified stream. After this the sender may still send PRIORITY
-// frames for this stream, which we can ignore.
-void SpdyTestDeframerImpl::OnRstStream(SpdyStreamId stream_id,
- SpdyErrorCode error_code) {
- SPDY_DVLOG(1) << "OnRstStream stream_id: " << stream_id
- << " error code: " << error_code;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_GT(stream_id, 0u);
-
- listener_->OnRstStream(
- std::make_unique<SpdyRstStreamIR>(stream_id, error_code));
-}
-
-// Called for an individual setting. There is no negotiation; the sender is
-// stating the value that the sender is using.
-void SpdyTestDeframerImpl::OnSetting(SpdySettingsId id, uint32_t value) {
- SPDY_DVLOG(1) << "OnSetting id: " << id << std::hex << " value: " << value;
- CHECK_EQ(frame_type_, SETTINGS)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(settings_ != nullptr);
- SpdyKnownSettingsId known_id;
- if (ParseSettingsId(id, &known_id)) {
- settings_->push_back(std::make_pair(known_id, value));
- settings_ir_->AddSetting(known_id, value);
- }
-}
-
-// Called at the start of a SETTINGS frame with setting entries, but not the
-// (required) ACK of a SETTINGS frame. There is no stream_id because
-// the settings apply to the entire connection, not to an individual stream.
-void SpdyTestDeframerImpl::OnSettings() {
- SPDY_DVLOG(1) << "OnSettings";
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_EQ(nullptr, settings_ir_.get());
- CHECK_EQ(nullptr, settings_.get());
- frame_type_ = SETTINGS;
- ack_ = false;
-
- settings_ = std::make_unique<SettingVector>();
- settings_ir_ = std::make_unique<SpdySettingsIR>();
-}
-
-void SpdyTestDeframerImpl::OnSettingsAck() {
- SPDY_DVLOG(1) << "OnSettingsAck";
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- auto ptr = std::make_unique<SpdySettingsIR>();
- ptr->set_is_ack(true);
- listener_->OnSettingsAck(std::move(ptr));
-}
-
-void SpdyTestDeframerImpl::OnSettingsEnd() {
- SPDY_DVLOG(1) << "OnSettingsEnd";
- CHECK_EQ(frame_type_, SETTINGS)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(!ack_);
- CHECK_NE(nullptr, settings_ir_.get());
- CHECK_NE(nullptr, settings_.get());
- listener_->OnSettings(std::move(settings_ir_), std::move(settings_));
- frame_type_ = UNSET;
-}
-
-// Called for a zero length DATA frame with the END_STREAM flag set, or at the
-// end a complete HPACK block (and its padding) that started with a HEADERS
-// frame with the END_STREAM flag set. Doesn't apply to PUSH_PROMISE frames
-// because they don't have END_STREAM flags.
-void SpdyTestDeframerImpl::OnStreamEnd(SpdyStreamId stream_id) {
- SPDY_DVLOG(1) << "OnStreamEnd stream_id: " << stream_id;
- CHECK_EQ(stream_id_, stream_id);
- CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
- frame_type_ == CONTINUATION)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(fin_);
-}
-
-// The data arg points into the non-padding payload of a DATA frame.
-// This must be a DATA frame (i.e. this method will not be
-// called for HEADERS or CONTINUATION frames).
-// This method may be called multiple times for a single DATA frame, depending
-// upon buffer boundaries.
-void SpdyTestDeframerImpl::OnStreamFrameData(SpdyStreamId stream_id,
- const char* data,
- size_t len) {
- SPDY_DVLOG(1) << "OnStreamFrameData stream_id: " << stream_id
- << " len: " << len;
- CHECK_EQ(stream_id_, stream_id);
- CHECK_EQ(frame_type_, DATA);
- data_->append(data, len);
-}
-
-// Called when receiving the padding length field at the start of the DATA frame
-// payload. value will be in the range 0 to 255.
-void SpdyTestDeframerImpl::OnStreamPadLength(SpdyStreamId stream_id,
- size_t value) {
- SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
- << " value: " << value;
- CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
- frame_type_ == PUSH_PROMISE)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_EQ(stream_id_, stream_id);
- CHECK_GE(255u, value);
- // Count the padding length byte against total padding.
- padding_len_ += 1;
- CHECK_EQ(1u, padding_len_);
-}
-
-// Called when padding is skipped over at the end of the DATA frame. len will
-// be in the range 1 to 255.
-void SpdyTestDeframerImpl::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
- SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
- << " len: " << len;
- CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
- frame_type_ == PUSH_PROMISE)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_EQ(stream_id_, stream_id);
- CHECK_LE(1u, len);
- CHECK_GE(255u, len);
- padding_len_ += len;
- CHECK_LE(padding_len_, 256u) << "len=" << len;
-}
-
-// WINDOW_UPDATE is supposed to be hop-by-hop, according to the spec.
-// stream_id is 0 if the update applies to the connection, else stream_id
-// will be the id of a stream previously seen, which maybe half or fully
-// closed.
-void SpdyTestDeframerImpl::OnWindowUpdate(SpdyStreamId stream_id,
- int delta_window_size) {
- SPDY_DVLOG(1) << "OnWindowUpdate stream_id: " << stream_id
- << " delta_window_size: " << delta_window_size;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK_NE(0, delta_window_size);
-
- listener_->OnWindowUpdate(
- std::make_unique<SpdyWindowUpdateIR>(stream_id, delta_window_size));
-}
-
-// Return true to indicate that the stream_id is valid; if not valid then
-// SpdyFramer considers the connection corrupted. Requires keeping track
-// of the set of currently open streams. For now we'll assume that unknown
-// frame types are unsupported.
-bool SpdyTestDeframerImpl::OnUnknownFrame(SpdyStreamId stream_id,
- uint8_t /*frame_type*/) {
- SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
- CHECK_EQ(frame_type_, UNSET)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- frame_type_ = UNKNOWN;
-
- stream_id_ = stream_id;
- return false;
-}
-
-// Callbacks defined in SpdyHeadersHandlerInterface.
-
-void SpdyTestDeframerImpl::OnHeaderBlockStart() {
- CHECK(frame_type_ == HEADERS || frame_type_ == PUSH_PROMISE)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(headers_ != nullptr);
- CHECK_EQ(0u, headers_->size());
- got_hpack_end_ = false;
-}
-
-void SpdyTestDeframerImpl::OnHeader(absl::string_view key,
- absl::string_view value) {
- CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
- frame_type_ == PUSH_PROMISE)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(!got_hpack_end_);
- HTTP2_DIE_IF_NULL(headers_)->emplace_back(std::string(key),
- std::string(value));
- HTTP2_DIE_IF_NULL(headers_handler_)->OnHeader(key, value);
-}
-
-void SpdyTestDeframerImpl::OnHeaderBlockEnd(
- size_t /* header_bytes_parsed */,
- size_t /* compressed_header_bytes_parsed */) {
- CHECK(headers_ != nullptr);
- CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
- frame_type_ == PUSH_PROMISE)
- << " frame_type_=" << Http2FrameTypeToString(frame_type_);
- CHECK(end_);
- CHECK(!got_hpack_end_);
- got_hpack_end_ = true;
-}
-
-class LoggingSpdyDeframerDelegate : public SpdyDeframerVisitorInterface {
- public:
- explicit LoggingSpdyDeframerDelegate(
- std::unique_ptr<SpdyDeframerVisitorInterface> wrapped)
- : wrapped_(std::move(wrapped)) {
- if (!wrapped_) {
- wrapped_ = std::make_unique<SpdyDeframerVisitorInterface>();
- }
- }
- ~LoggingSpdyDeframerDelegate() override = default;
-
- void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc";
- wrapped_->OnAltSvc(std::move(frame));
- }
- void OnData(std::unique_ptr<SpdyDataIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnData";
- wrapped_->OnData(std::move(frame));
- }
- void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnGoAway";
- wrapped_->OnGoAway(std::move(frame));
- }
-
- // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
- // significantly modifies the headers, so the actual header entries (name
- // and value strings) are provided in a vector.
- void OnHeaders(std::unique_ptr<SpdyHeadersIR> frame,
- std::unique_ptr<StringPairVector> headers) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnHeaders";
- wrapped_->OnHeaders(std::move(frame), std::move(headers));
- }
-
- void OnPing(std::unique_ptr<SpdyPingIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPing";
- wrapped_->OnPing(std::move(frame));
- }
- void OnPingAck(std::unique_ptr<SpdyPingIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPingAck";
- wrapped_->OnPingAck(std::move(frame));
- }
-
- void OnPriority(std::unique_ptr<SpdyPriorityIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPriority";
- wrapped_->OnPriority(std::move(frame));
- }
-
- // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
- // significantly modifies the headers, so the actual header entries (name
- // and value strings) are provided in a vector.
- void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> frame,
- std::unique_ptr<StringPairVector> headers) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPushPromise";
- wrapped_->OnPushPromise(std::move(frame), std::move(headers));
- }
-
- void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnRstStream";
- wrapped_->OnRstStream(std::move(frame));
- }
-
- // SpdySettingsIR has a map for settings, so loses info about the order of
- // settings, and whether the same setting appeared more than once, so the
- // the actual settings (parameter and value) are provided in a vector.
- void OnSettings(std::unique_ptr<SpdySettingsIR> frame,
- std::unique_ptr<SettingVector> settings) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettings";
- wrapped_->OnSettings(std::move(frame), std::move(settings));
- }
-
- // A settings frame with an ACK has no content, but for uniformity passing
- // a frame with the ACK flag set.
- void OnSettingsAck(std::unique_ptr<SpdySettingsIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettingsAck";
- wrapped_->OnSettingsAck(std::move(frame));
- }
-
- void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnWindowUpdate";
- wrapped_->OnWindowUpdate(std::move(frame));
- }
-
- // The SpdyFramer will not process any more data at this point.
- void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
- SpdyTestDeframer* deframer) override {
- SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnError";
- wrapped_->OnError(error, deframer);
- }
-
- private:
- std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_;
-};
-
-// static
-std::unique_ptr<SpdyDeframerVisitorInterface>
-SpdyDeframerVisitorInterface::LogBeforeVisiting(
- std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_listener) {
- return std::make_unique<LoggingSpdyDeframerDelegate>(
- std::move(wrapped_listener));
-}
-
-CollectedFrame::CollectedFrame() = default;
-
-CollectedFrame::CollectedFrame(CollectedFrame&& other)
- : frame_ir(std::move(other.frame_ir)),
- headers(std::move(other.headers)),
- settings(std::move(other.settings)),
- error_reported(other.error_reported) {}
-
-CollectedFrame::~CollectedFrame() = default;
-
-CollectedFrame& CollectedFrame::operator=(CollectedFrame&& other) {
- frame_ir = std::move(other.frame_ir);
- headers = std::move(other.headers);
- settings = std::move(other.settings);
- error_reported = other.error_reported;
- return *this;
-}
-
-AssertionResult CollectedFrame::VerifyHasHeaders(
- const StringPairVector& expected_headers) const {
- VERIFY_NE(headers.get(), nullptr);
- VERIFY_THAT(*headers, ::testing::ContainerEq(expected_headers));
- return AssertionSuccess();
-}
-
-AssertionResult CollectedFrame::VerifyHasSettings(
- const SettingVector& expected_settings) const {
- VERIFY_NE(settings.get(), nullptr);
- VERIFY_THAT(*settings, testing::ContainerEq(expected_settings));
- return AssertionSuccess();
-}
-
-DeframerCallbackCollector::DeframerCallbackCollector(
- std::vector<CollectedFrame>* collected_frames)
- : collected_frames_(HTTP2_DIE_IF_NULL(collected_frames)) {}
-
-void DeframerCallbackCollector::OnAltSvc(
- std::unique_ptr<SpdyAltSvcIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-void DeframerCallbackCollector::OnData(std::unique_ptr<SpdyDataIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-void DeframerCallbackCollector::OnGoAway(
- std::unique_ptr<SpdyGoAwayIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-// significantly modifies the headers, so the actual header entries (name
-// and value strings) are provided in a vector.
-void DeframerCallbackCollector::OnHeaders(
- std::unique_ptr<SpdyHeadersIR> frame_ir,
- std::unique_ptr<StringPairVector> headers) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- cf.headers = std::move(headers);
- collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPing(std::unique_ptr<SpdyPingIR> frame_ir) {
- EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPingAck(
- std::unique_ptr<SpdyPingIR> frame_ir) {
- EXPECT_TRUE(frame_ir && frame_ir->is_ack());
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnPriority(
- std::unique_ptr<SpdyPriorityIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
-// significantly modifies the headers, so the actual header entries (name
-// and value strings) are provided in a vector.
-void DeframerCallbackCollector::OnPushPromise(
- std::unique_ptr<SpdyPushPromiseIR> frame_ir,
- std::unique_ptr<StringPairVector> headers) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- cf.headers = std::move(headers);
- collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnRstStream(
- std::unique_ptr<SpdyRstStreamIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-// SpdySettingsIR has a map for settings, so loses info about the order of
-// settings, and whether the same setting appeared more than once, so the
-// the actual settings (parameter and value) are provided in a vector.
-void DeframerCallbackCollector::OnSettings(
- std::unique_ptr<SpdySettingsIR> frame_ir,
- std::unique_ptr<SettingVector> settings) {
- EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- cf.settings = std::move(settings);
- collected_frames_->push_back(std::move(cf));
-}
-
-// A settings frame_ir with an ACK has no content, but for uniformity passing
-// a frame_ir with the ACK flag set.
-void DeframerCallbackCollector::OnSettingsAck(
- std::unique_ptr<SpdySettingsIR> frame_ir) {
- EXPECT_TRUE(frame_ir && frame_ir->is_ack());
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-void DeframerCallbackCollector::OnWindowUpdate(
- std::unique_ptr<SpdyWindowUpdateIR> frame_ir) {
- CollectedFrame cf;
- cf.frame_ir = std::move(frame_ir);
- collected_frames_->push_back(std::move(cf));
-}
-
-// The SpdyFramer will not process any more data at this point.
-void DeframerCallbackCollector::OnError(
- http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
- SpdyTestDeframer* /*deframer*/) {
- CollectedFrame cf;
- cf.error_reported = true;
- collected_frames_->push_back(std::move(cf));
-}
-
-} // namespace test
-} // namespace spdy
diff --git a/spdy/core/spdy_deframer_visitor.h b/spdy/core/spdy_deframer_visitor.h
deleted file mode 100644
index f17df98..0000000
--- a/spdy/core/spdy_deframer_visitor.h
+++ /dev/null
@@ -1,247 +0,0 @@
-// 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.
-
-#ifndef QUICHE_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
-#define QUICHE_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
-
-// Supports testing by converting callbacks to SpdyFramerVisitorInterface into
-// callbacks to SpdyDeframerVisitorInterface, whose arguments are generally
-// SpdyFrameIR instances. This enables a test client or test backend to operate
-// at a level between the low-level callbacks of SpdyFramerVisitorInterface and
-// the much higher level of entire messages (i.e. headers, body, trailers).
-// Where possible the converter (SpdyTestDeframer) tries to preserve information
-// that might be useful to tests (e.g. the order of headers or the amount of
-// padding); the design also aims to allow tests to be concise, ideally
-// supporting gMock style EXPECT_CALL(visitor, OnHeaders(...matchers...))
-// without too much boilerplate.
-//
-// Only supports HTTP/2 for the moment.
-//
-// Example of usage:
-//
-// SpdyFramer framer(HTTP2);
-//
-// // Need to call SpdyTestDeframer::AtFrameEnd() after processing each
-// // frame, so tell SpdyFramer to stop after each.
-// framer.set_process_single_input_frame(true);
-//
-// // Need the new OnHeader callbacks.
-// framer.set_use_new_methods_for_test(true);
-//
-// // Create your visitor, a subclass of SpdyDeframerVisitorInterface.
-// // For example, using DeframerCallbackCollector to collect frames:
-// std::vector<CollectedFrame> collected_frames;
-// auto your_visitor = std::make_unique<DeframerCallbackCollector>(
-// &collected_frames);
-//
-// // Transfer ownership of your visitor to the converter, which ensures that
-// // your visitor stays alive while the converter needs to call it.
-// auto the_deframer = SpdyTestDeframer::CreateConverter(
-// std::move(your_visitor));
-//
-// // Tell the framer to notify SpdyTestDeframer of the decoded frame
-// // details.
-// framer.set_visitor(the_deframer.get());
-//
-// // Process frames.
-// absl::string_view input = ...
-// while (!input.empty() && !framer.HasError()) {
-// size_t consumed = framer.ProcessInput(input.data(), input.size());
-// input.remove_prefix(consumed);
-// if (framer.state() == SpdyFramer::SPDY_READY_FOR_FRAME) {
-// the_deframer->AtFrameEnd();
-// }
-// }
-//
-// // Make sure that the correct frames were received. For example:
-// ASSERT_EQ(collected_frames.size(), 3);
-//
-// SpdyDataIR expected1(7 /*stream_id*/, "Data Payload");
-// expected1.set_padding_len(17);
-// EXPECT_TRUE(collected_frames[0].VerifyEquals(expected1));
-//
-// // Repeat for the other frames.
-//
-// Note that you could also seed the subclass of SpdyDeframerVisitorInterface
-// with the expected frames, which it would pop-off the list as its expectations
-// are met.
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-namespace spdy {
-namespace test {
-
-// Non-lossy representation of a SETTINGS frame payload.
-typedef std::vector<std::pair<SpdyKnownSettingsId, uint32_t>> SettingVector;
-
-// StringPairVector is used to record information lost by SpdyHeaderBlock, in
-// particular the order of each header entry, though it doesn't expose the
-// inner details of the HPACK block, such as the type of encoding selected
-// for each header entry, nor dynamic table size changes.
-typedef std::pair<std::string, std::string> StringPair;
-typedef std::vector<StringPair> StringPairVector;
-
-// Forward decl.
-class SpdyTestDeframer;
-
-// Note that this only roughly captures the frames, as padding bytes are lost,
-// continuation frames are combined with their leading HEADERS or PUSH_PROMISE,
-// the details of the HPACK encoding are lost, leaving
-// only the list of header entries (name and value strings). If really helpful,
-// we could add a SpdyRawDeframerVisitorInterface that gets the HPACK bytes,
-// and receives continuation frames. For more info we'd need to improve
-// SpdyFramerVisitorInterface.
-class SpdyDeframerVisitorInterface {
- public:
- virtual ~SpdyDeframerVisitorInterface() {}
-
- // Wrap a visitor in another SpdyDeframerVisitorInterface that will
- // DVLOG each call, and will then forward the calls to the wrapped visitor
- // (if provided; nullptr is OK). Takes ownership of the wrapped visitor.
- static std::unique_ptr<SpdyDeframerVisitorInterface> LogBeforeVisiting(
- std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_visitor);
-
- virtual void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> /*frame*/) {}
- virtual void OnData(std::unique_ptr<SpdyDataIR> /*frame*/) {}
- virtual void OnGoAway(std::unique_ptr<SpdyGoAwayIR> /*frame*/) {}
-
- // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
- // significantly modifies the headers, so the actual header entries (name
- // and value strings) are provided in a vector.
- virtual void OnHeaders(std::unique_ptr<SpdyHeadersIR> /*frame*/,
- std::unique_ptr<StringPairVector> /*headers*/) {}
-
- virtual void OnPing(std::unique_ptr<SpdyPingIR> /*frame*/) {}
- virtual void OnPingAck(std::unique_ptr<SpdyPingIR> /*frame*/);
- virtual void OnPriority(std::unique_ptr<SpdyPriorityIR> /*frame*/) {}
-
- // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
- // significantly modifies the headers, so the actual header entries (name
- // and value strings) are provided in a vector.
- virtual void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> /*frame*/,
- std::unique_ptr<StringPairVector> /*headers*/) {}
-
- virtual void OnRstStream(std::unique_ptr<SpdyRstStreamIR> /*frame*/) {}
-
- // SpdySettingsIR has a map for settings, so loses info about the order of
- // settings, and whether the same setting appeared more than once, so the
- // the actual settings (parameter and value) are provided in a vector.
- virtual void OnSettings(std::unique_ptr<SpdySettingsIR> /*frame*/,
- std::unique_ptr<SettingVector> /*settings*/) {}
-
- // A settings frame with an ACK has no content, but for uniformity passing
- // a frame with the ACK flag set.
- virtual void OnSettingsAck(std::unique_ptr<SpdySettingsIR> /*frame*/);
-
- virtual void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> /*frame*/) {}
-
- // The SpdyFramer will not process any more data at this point.
- virtual void OnError(http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
- SpdyTestDeframer* /*deframer*/) {}
-};
-
-class SpdyTestDeframer : public SpdyFramerVisitorInterface {
- public:
- ~SpdyTestDeframer() override {}
-
- // Creates a SpdyFramerVisitorInterface that builds SpdyFrameIR concrete
- // instances based on the callbacks it receives; when an entire frame is
- // decoded/reconstructed it calls the passed in SpdyDeframerVisitorInterface.
- // Transfers ownership of visitor to the new SpdyTestDeframer, which ensures
- // that it continues to exist while the SpdyTestDeframer exists.
- static std::unique_ptr<SpdyTestDeframer> CreateConverter(
- std::unique_ptr<SpdyDeframerVisitorInterface> visitor);
-
- // Call to notify the deframer that the SpdyFramer has returned after reaching
- // the end of decoding a frame. This is used to flush info about some frame
- // types where we don't get a clear end signal; others are flushed (i.e. the
- // appropriate call to the SpdyDeframerVisitorInterface method is invoked)
- // as they're decoded by SpdyFramer and it calls the deframer. See the
- // example in the comments at the top of this file.
- virtual bool AtFrameEnd() = 0;
-
- protected:
- SpdyTestDeframer() {}
- SpdyTestDeframer(const SpdyTestDeframer&) = delete;
- SpdyTestDeframer& operator=(const SpdyTestDeframer&) = delete;
-};
-
-// CollectedFrame holds the result of one call to SpdyDeframerVisitorInterface,
-// as recorded by DeframerCallbackCollector.
-struct CollectedFrame {
- CollectedFrame();
- CollectedFrame(CollectedFrame&& other);
- ~CollectedFrame();
- CollectedFrame& operator=(CollectedFrame&& other);
-
- // Compare a SpdyFrameIR sub-class instance, expected_ir, against the
- // collected SpdyFrameIR.
- template <class T,
- typename X =
- typename std::enable_if<std::is_base_of<SpdyFrameIR, T>::value>>
- ::testing::AssertionResult VerifyHasFrame(const T& expected_ir) const {
- return VerifySpdyFrameIREquals(expected_ir, frame_ir.get());
- }
-
- // Compare the collected headers against a StringPairVector. Ignores
- // this->frame_ir.
- ::testing::AssertionResult VerifyHasHeaders(
- const StringPairVector& expected_headers) const;
-
- // Compare the collected settings (parameter and value pairs) against
- // expected_settings. Ignores this->frame_ir.
- ::testing::AssertionResult VerifyHasSettings(
- const SettingVector& expected_settings) const;
-
- std::unique_ptr<SpdyFrameIR> frame_ir;
- std::unique_ptr<StringPairVector> headers;
- std::unique_ptr<SettingVector> settings;
- bool error_reported = false;
-};
-
-// Creates a CollectedFrame instance for each callback, storing it in the
-// vector provided to the constructor.
-class DeframerCallbackCollector : public SpdyDeframerVisitorInterface {
- public:
- explicit DeframerCallbackCollector(
- std::vector<CollectedFrame>* collected_frames);
- ~DeframerCallbackCollector() override {}
-
- void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame_ir) override;
- void OnData(std::unique_ptr<SpdyDataIR> frame_ir) override;
- void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame_ir) override;
- void OnHeaders(std::unique_ptr<SpdyHeadersIR> frame_ir,
- std::unique_ptr<StringPairVector> headers) override;
- void OnPing(std::unique_ptr<SpdyPingIR> frame_ir) override;
- void OnPingAck(std::unique_ptr<SpdyPingIR> frame_ir) override;
- void OnPriority(std::unique_ptr<SpdyPriorityIR> frame_ir) override;
- void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> frame_ir,
- std::unique_ptr<StringPairVector> headers) override;
- void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame_ir) override;
- void OnSettings(std::unique_ptr<SpdySettingsIR> frame_ir,
- std::unique_ptr<SettingVector> settings) override;
- void OnSettingsAck(std::unique_ptr<SpdySettingsIR> frame_ir) override;
- void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame_ir) override;
- void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
- SpdyTestDeframer* deframer) override;
-
- private:
- std::vector<CollectedFrame>* collected_frames_;
-};
-
-} // namespace test
-} // namespace spdy
-
-#endif // QUICHE_SPDY_CORE_SPDY_DEFRAMER_VISITOR_H_
diff --git a/spdy/core/spdy_deframer_visitor_test.cc b/spdy/core/spdy_deframer_visitor_test.cc
deleted file mode 100644
index b90d0b0..0000000
--- a/spdy/core/spdy_deframer_visitor_test.cc
+++ /dev/null
@@ -1,246 +0,0 @@
-// 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 "net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h"
-
-#include <stdlib.h>
-
-#include <algorithm>
-#include <limits>
-
-#include "net/third_party/quiche/src/http2/test_tools/http2_random.h"
-#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
-#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
-#include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_protocol_test_utils.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
-
-namespace spdy {
-namespace test {
-namespace {
-
-class SpdyDeframerVisitorTest : public QuicheTest {
- protected:
- SpdyDeframerVisitorTest() : encoder_(SpdyFramer::ENABLE_COMPRESSION) {
- decoder_.set_process_single_input_frame(true);
- auto collector =
- std::make_unique<DeframerCallbackCollector>(&collected_frames_);
- auto log_and_collect =
- SpdyDeframerVisitorInterface::LogBeforeVisiting(std::move(collector));
- deframer_ = SpdyTestDeframer::CreateConverter(std::move(log_and_collect));
- decoder_.set_visitor(deframer_.get());
- }
-
- bool DeframeInput(const char* input, size_t size) {
- size_t input_remaining = size;
- while (input_remaining > 0 &&
- decoder_.spdy_framer_error() ==
- http2::Http2DecoderAdapter::SPDY_NO_ERROR) {
- // To make the tests more interesting, we feed random (and small) chunks
- // into the framer. This simulates getting strange-sized reads from
- // the socket.
- const size_t kMaxReadSize = 32;
- size_t bytes_read =
- (random_.Uniform(std::min(input_remaining, kMaxReadSize))) + 1;
- size_t bytes_processed = decoder_.ProcessInput(input, bytes_read);
- input_remaining -= bytes_processed;
- input += bytes_processed;
- if (decoder_.state() ==
- http2::Http2DecoderAdapter::SPDY_READY_FOR_FRAME) {
- deframer_->AtFrameEnd();
- }
- }
- return (input_remaining == 0 &&
- decoder_.spdy_framer_error() ==
- http2::Http2DecoderAdapter::SPDY_NO_ERROR);
- }
-
- SpdyFramer encoder_;
- http2::Http2DecoderAdapter decoder_;
- std::vector<CollectedFrame> collected_frames_;
- std::unique_ptr<SpdyTestDeframer> deframer_;
-
- private:
- http2::test::Http2Random random_;
-};
-
-TEST_F(SpdyDeframerVisitorTest, DataFrame) {
- const char kFrameData[] = {
- 0x00, 0x00, 0x0d, // Length = 13.
- 0x00, // DATA
- 0x08, // PADDED
- 0x00, 0x00, 0x00, 0x01, // Stream 1
- 0x07, // Pad length field.
- 'h', 'e', 'l', 'l', // Data
- 'o', // More Data
- 0x00, 0x00, 0x00, 0x00, // Padding
- 0x00, 0x00, 0x00 // More Padding
- };
-
- EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
- ASSERT_EQ(1u, collected_frames_.size());
- const CollectedFrame& cf0 = collected_frames_[0];
- ASSERT_NE(cf0.frame_ir, nullptr);
-
- SpdyDataIR expected_ir(/* stream_id = */ 1, "hello");
- expected_ir.set_padding_len(8);
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-}
-
-TEST_F(SpdyDeframerVisitorTest, HeaderFrameWithContinuation) {
- const char kFrameData[] = {
- 0x00, 0x00, 0x05, // Payload Length: 5
- 0x01, // Type: HEADERS
- 0x09, // Flags: PADDED | END_STREAM
- 0x00, 0x00, 0x00, 0x01, // Stream: 1
- 0x04, // Padding Length: 4
- 0x00, 0x00, 0x00, 0x00, // Padding
- /* Second Frame */
- 0x00, 0x00, 0x12, // Payload Length: 18
- 0x09, // Type: CONTINUATION
- 0x04, // Flags: END_HEADERS
- 0x00, 0x00, 0x00, 0x01, // Stream: 1
- 0x00, // Unindexed, literal name & value
- 0x03, 0x62, 0x61, 0x72, // Name len and name (3, "bar")
- 0x03, 0x66, 0x6f, 0x6f, // Value len and value (3, "foo")
- 0x00, // Unindexed, literal name & value
- 0x03, 0x66, 0x6f, 0x6f, // Name len and name (3, "foo")
- 0x03, 0x62, 0x61, 0x72, // Value len and value (3, "bar")
- };
-
- EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
- ASSERT_EQ(1u, collected_frames_.size());
- const CollectedFrame& cf0 = collected_frames_[0];
-
- StringPairVector headers;
- headers.push_back({"bar", "foo"});
- headers.push_back({"foo", "bar"});
-
- EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
-
- SpdyHeadersIR expected_ir(/* stream_id = */ 1);
- // Yet again SpdyFramerVisitorInterface is lossy: it doesn't call OnPadding
- // for HEADERS, just for DATA. Sigh.
- // expected_ir.set_padding_len(5);
- expected_ir.set_fin(true);
- for (const auto& nv : headers) {
- expected_ir.SetHeader(nv.first, nv.second);
- }
-
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
- // Confirm that mismatches are also detected.
- headers.push_back({"baz", "bing"});
- EXPECT_FALSE(cf0.VerifyHasHeaders(headers));
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
- headers.pop_back();
- EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
- expected_ir.SetHeader("baz", "bing");
- EXPECT_FALSE(cf0.VerifyHasFrame(expected_ir));
- EXPECT_TRUE(cf0.VerifyHasHeaders(headers));
-}
-
-TEST_F(SpdyDeframerVisitorTest, PriorityFrame) {
- const char kFrameData[] = {
- 0x00, 0x00, 0x05, // Length: 5
- 0x02, // Type: PRIORITY
- 0x00, // Flags: none
- 0x00, 0x00, 0x00, 0x65, // Stream: 101
- '\x80', 0x00, 0x00, 0x01, // Parent: 1 (Exclusive)
- 0x10, // Weight: 17
- };
-
- EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
- ASSERT_EQ(1u, collected_frames_.size());
- const CollectedFrame& cf0 = collected_frames_[0];
-
- SpdyPriorityIR expected_ir(/* stream_id = */ 101,
- /* parent_stream_id = */ 1, /* weight = */ 17,
- /* exclusive = */ true);
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
- // Confirm that mismatches are also detected.
- EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 1, 16, true)));
- EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 50, 17, true)));
- EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(201, 1, 17, true)));
- EXPECT_FALSE(cf0.VerifyHasFrame(SpdyPriorityIR(101, 1, 17, false)));
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_RstStreamFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, SettingsFrame) {
- // Settings frame with two entries for the same parameter but with different
- // values. The last one will be in the decoded SpdySettingsIR, but the vector
- // of settings will have both, in the same order.
- const char kFrameData[] = {
- 0x00, 0x00, 0x0c, // Length
- 0x04, // Type (SETTINGS)
- 0x00, // Flags
- 0x00, 0x00, 0x00, 0x00, // Stream id (must be zero)
- 0x00, 0x04, // Setting id (SETTINGS_INITIAL_WINDOW_SIZE)
- 0x0a, 0x0b, 0x0c, 0x0d, // Setting value
- 0x00, 0x04, // Setting id (SETTINGS_INITIAL_WINDOW_SIZE)
- 0x00, 0x00, 0x00, '\xff', // Setting value
- };
-
- EXPECT_TRUE(DeframeInput(kFrameData, sizeof kFrameData));
- ASSERT_EQ(1u, collected_frames_.size());
- const CollectedFrame& cf0 = collected_frames_[0];
- ASSERT_NE(cf0.frame_ir, nullptr);
-
- SpdySettingsIR expected_ir;
- expected_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 255);
- EXPECT_TRUE(cf0.VerifyHasFrame(expected_ir));
-
- SettingVector expected_settings;
- expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 0x0a0b0c0d});
- expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 255});
-
- EXPECT_TRUE(cf0.VerifyHasSettings(expected_settings));
-
- // Confirm that mismatches are also detected.
- expected_settings.push_back({SETTINGS_INITIAL_WINDOW_SIZE, 65536});
- EXPECT_FALSE(cf0.VerifyHasSettings(expected_settings));
-
- expected_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 65536);
- EXPECT_FALSE(cf0.VerifyHasFrame(expected_ir));
-
- SpdySettingsIR unexpected_ir;
- unexpected_ir.set_is_ack(true);
- EXPECT_FALSE(cf0.VerifyHasFrame(unexpected_ir));
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_PushPromiseFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_PingFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_GoAwayFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_WindowUpdateFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-TEST_F(SpdyDeframerVisitorTest, DISABLED_AltSvcFrame) {
- // TODO(jamessynge): Please implement.
-}
-
-} // namespace
-} // namespace test
-} // namespace spdy