| Index: net/spdy/spdy_deframer_visitor.cc
|
| diff --git a/net/spdy/spdy_deframer_visitor.cc b/net/spdy/spdy_deframer_visitor.cc
|
| deleted file mode 100644
|
| index c6075c962dfad3275d9cb7596fe3ce5c41623734..0000000000000000000000000000000000000000
|
| --- a/net/spdy/spdy_deframer_visitor.cc
|
| +++ /dev/null
|
| @@ -1,1025 +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/spdy/spdy_deframer_visitor.h"
|
| -
|
| -#include <stdlib.h>
|
| -
|
| -#include <algorithm>
|
| -#include <cstdint>
|
| -#include <limits>
|
| -
|
| -#include "base/logging.h"
|
| -#include "base/memory/ptr_util.h"
|
| -#include "net/spdy/hpack/hpack_constants.h"
|
| -#include "net/spdy/mock_spdy_framer_visitor.h"
|
| -#include "net/spdy/spdy_frame_builder.h"
|
| -#include "net/spdy/spdy_frame_reader.h"
|
| -#include "net/spdy/spdy_protocol.h"
|
| -#include "net/spdy/spdy_test_utils.h"
|
| -
|
| -using ::base::MakeUnique;
|
| -using ::testing::AssertionFailure;
|
| -using ::testing::AssertionResult;
|
| -using ::testing::AssertionSuccess;
|
| -
|
| -namespace net {
|
| -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 //net/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 //net/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 //net/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 //net/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 //net/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_);
|
| - }
|
| - ~SpdyTestDeframerImpl() override {}
|
| -
|
| - 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,
|
| - SpdyStringPiece 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, bool end_headers) override;
|
| - void OnDataFrameHeader(SpdyStreamId stream_id,
|
| - size_t length,
|
| - bool fin) override;
|
| - void OnError(SpdyFramer* framer) 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(SpdySettingsIds id, uint32_t value) override;
|
| - void OnSettings(bool clear_persisted) 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 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(SpdyStringPiece key, SpdyStringPiece value) override;
|
| - void OnHeaderBlockEnd(size_t header_bytes_parsed) 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<SpdyString> 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<SpdyString> goaway_description_;
|
| - std::unique_ptr<StringPairVector> headers_;
|
| - std::unique_ptr<SettingVector> settings_;
|
| - std::unique_ptr<TestHeadersHandler> 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_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SpdyTestDeframerImpl);
|
| -};
|
| -
|
| -// static
|
| -std::unique_ptr<SpdyTestDeframer> SpdyTestDeframer::CreateConverter(
|
| - std::unique_ptr<SpdyDeframerVisitorInterface> listener) {
|
| - return MakeUnique<SpdyTestDeframerImpl>(std::move(listener));
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::AtDataEnd() {
|
| - DVLOG(1) << "AtDataEnd";
|
| - CHECK_EQ(data_len_, padding_len_ + data_->size());
|
| - auto ptr = MakeUnique<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() {
|
| - DVLOG(1) << "AtDataEnd";
|
| - CHECK_EQ(frame_type_, GOAWAY);
|
| - CHECK(goaway_description_);
|
| - if (goaway_description_->empty()) {
|
| - listener_->OnGoAway(std::move(goaway_ir_));
|
| - } else {
|
| - listener_->OnGoAway(MakeUnique<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() {
|
| - 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_);
|
| - CHECK(headers_);
|
| - CHECK(headers_handler_);
|
| -
|
| - 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() {
|
| - 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_);
|
| - CHECK(headers_);
|
| - CHECK(headers_handler_);
|
| -
|
| - 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 {
|
| - 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,
|
| - SpdyStringPiece origin,
|
| - const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
|
| - DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
|
| - CHECK_EQ(frame_type_, UNSET) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - CHECK_GT(stream_id, 0u);
|
| - auto ptr = MakeUnique<SpdyAltSvcIR>(stream_id);
|
| - ptr->set_origin(SpdyString(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) {
|
| - 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) {
|
| - 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_.reset(new SpdyString());
|
| -}
|
| -
|
| -// The SpdyFramer will not process any more data at this point.
|
| -void SpdyTestDeframerImpl::OnError(SpdyFramer* framer) {
|
| - DVLOG(1) << "SpdyFramer detected an error in the stream: "
|
| - << SpdyFramer::SpdyFramerErrorToString(framer->spdy_framer_error())
|
| - << " frame_type_: " << Http2FrameTypeToString(frame_type_);
|
| - listener_->OnError(framer, 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_good_stream_id,
|
| - SpdyErrorCode error_code) {
|
| - DVLOG(1) << "OnGoAway last_good_stream_id: " << last_good_stream_id
|
| - << " error code: " << error_code;
|
| - CHECK_EQ(frame_type_, UNSET) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - frame_type_ = GOAWAY;
|
| - goaway_ir_ = MakeUnique<SpdyGoAwayIR>(last_good_stream_id, error_code, "");
|
| - goaway_description_.reset(new SpdyString());
|
| -}
|
| -
|
| -// If len==0 then we've reached the end of the GOAWAY frame.
|
| -bool SpdyTestDeframerImpl::OnGoAwayFrameData(const char* goaway_data,
|
| - size_t len) {
|
| - DVLOG(1) << "OnGoAwayFrameData";
|
| - CHECK_EQ(frame_type_, GOAWAY) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - CHECK(goaway_description_);
|
| - goaway_description_->append(goaway_data, len);
|
| - return true;
|
| -}
|
| -
|
| -SpdyHeadersHandlerInterface* SpdyTestDeframerImpl::OnHeaderFrameStart(
|
| - SpdyStreamId stream_id) {
|
| - return this;
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnHeaderFrameEnd(SpdyStreamId stream_id,
|
| - bool end_headers) {
|
| - DVLOG(1) << "OnHeaderFrameEnd stream_id: " << stream_id
|
| - << " end_headers: " << (end_headers ? "true" : "false");
|
| -}
|
| -
|
| -// 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) {
|
| - 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_.reset(new StringPairVector());
|
| - headers_handler_.reset(new TestHeadersHandler());
|
| - headers_ir_ = MakeUnique<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) {
|
| - 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 = MakeUnique<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) {
|
| - DVLOG(1) << "OnPriority stream_id: " << stream_id;
|
| - CHECK_EQ(frame_type_, UNSET) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - CHECK_GT(stream_id, 0u);
|
| -
|
| - listener_->OnPriority(MakeUnique<SpdyPriorityIR>(stream_id, parent_stream_id,
|
| - weight, exclusive));
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnPushPromise(SpdyStreamId stream_id,
|
| - SpdyStreamId promised_stream_id,
|
| - bool end) {
|
| - 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_.reset(new StringPairVector());
|
| - headers_handler_.reset(new TestHeadersHandler());
|
| - push_promise_ir_ =
|
| - MakeUnique<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) {
|
| - 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(MakeUnique<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(SpdySettingsIds id, uint32_t value) {
|
| - DVLOG(1) << "OnSetting id: " << id << std::hex << " value: " << value;
|
| - CHECK_EQ(frame_type_, SETTINGS) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - CHECK(settings_);
|
| - settings_->push_back(std::make_pair(id, value));
|
| - settings_ir_->AddSetting(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.
|
| -// The |clear_persisted| flag is a pre-HTTP/2 remnant.
|
| -void SpdyTestDeframerImpl::OnSettings(bool /*clear_persisted*/) {
|
| - 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_.reset(new SettingVector());
|
| - settings_ir_.reset(new SpdySettingsIR());
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnSettingsAck() {
|
| - DVLOG(1) << "OnSettingsAck";
|
| - CHECK_EQ(frame_type_, UNSET) << " frame_type_="
|
| - << Http2FrameTypeToString(frame_type_);
|
| - auto ptr = MakeUnique<SpdySettingsIR>();
|
| - ptr->set_is_ack(true);
|
| - listener_->OnSettingsAck(std::move(ptr));
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnSettingsEnd() {
|
| - 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) {
|
| - 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) {
|
| - 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 padding is skipped over, including the padding length field at
|
| -// the start of the frame payload, and the actual padding at the end. len will
|
| -// be in the range 1 to 255.
|
| -void SpdyTestDeframerImpl::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
|
| - 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) {
|
| - 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(
|
| - MakeUnique<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) {
|
| - 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_);
|
| - CHECK_EQ(0u, headers_->size());
|
| - got_hpack_end_ = false;
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnHeader(SpdyStringPiece key,
|
| - SpdyStringPiece value) {
|
| - CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
|
| - frame_type_ == PUSH_PROMISE)
|
| - << " frame_type_=" << Http2FrameTypeToString(frame_type_);
|
| - CHECK(!got_hpack_end_);
|
| - CHECK(headers_);
|
| - headers_->emplace_back(SpdyString(key), SpdyString(value));
|
| - CHECK(headers_handler_);
|
| - headers_handler_->OnHeader(key, value);
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnHeaderBlockEnd(size_t header_bytes_parsed) {
|
| - CHECK(headers_);
|
| - 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;
|
| -}
|
| -
|
| -void SpdyTestDeframerImpl::OnHeaderBlockEnd(
|
| - size_t /* header_bytes_parsed */,
|
| - size_t /* compressed_header_bytes_parsed */) {
|
| - CHECK(headers_);
|
| - 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_ = MakeUnique<SpdyDeframerVisitorInterface>();
|
| - }
|
| - }
|
| - ~LoggingSpdyDeframerDelegate() override {}
|
| -
|
| - void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc";
|
| - wrapped_->OnAltSvc(std::move(frame));
|
| - }
|
| - void OnData(std::unique_ptr<SpdyDataIR> frame) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnData";
|
| - wrapped_->OnData(std::move(frame));
|
| - }
|
| - void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame) override {
|
| - 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 {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnHeaders";
|
| - wrapped_->OnHeaders(std::move(frame), std::move(headers));
|
| - }
|
| -
|
| - void OnPing(std::unique_ptr<SpdyPingIR> frame) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPing";
|
| - wrapped_->OnPing(std::move(frame));
|
| - }
|
| - void OnPingAck(std::unique_ptr<SpdyPingIR> frame) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPingAck";
|
| - wrapped_->OnPingAck(std::move(frame));
|
| - }
|
| -
|
| - void OnPriority(std::unique_ptr<SpdyPriorityIR> frame) override {
|
| - 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 {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPushPromise";
|
| - wrapped_->OnPushPromise(std::move(frame), std::move(headers));
|
| - }
|
| -
|
| - void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame) override {
|
| - 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 {
|
| - 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 {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettingsAck";
|
| - wrapped_->OnSettingsAck(std::move(frame));
|
| - }
|
| -
|
| - void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnWindowUpdate";
|
| - wrapped_->OnWindowUpdate(std::move(frame));
|
| - }
|
| -
|
| - // The SpdyFramer will not process any more data at this point.
|
| - void OnError(SpdyFramer* framer, SpdyTestDeframer* deframer) override {
|
| - DVLOG(1) << "LoggingSpdyDeframerDelegate::OnError";
|
| - wrapped_->OnError(framer, deframer);
|
| - }
|
| -
|
| - private:
|
| - std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_;
|
| -};
|
| -
|
| -// static
|
| -std::unique_ptr<SpdyDeframerVisitorInterface>
|
| -SpdyDeframerVisitorInterface::LogBeforeVisiting(
|
| - std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_listener) {
|
| - return MakeUnique<LoggingSpdyDeframerDelegate>(std::move(wrapped_listener));
|
| -}
|
| -
|
| -CollectedFrame::CollectedFrame() {}
|
| -
|
| -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() {}
|
| -
|
| -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 {
|
| - if (headers.get() == nullptr)
|
| - return AssertionFailure();
|
| - if (*headers != expected_headers)
|
| - return AssertionFailure();
|
| -
|
| - return AssertionSuccess();
|
| -}
|
| -
|
| -AssertionResult CollectedFrame::VerifyHasSettings(
|
| - const SettingVector& expected_settings) const {
|
| - if (settings.get() == nullptr)
|
| - return AssertionFailure();
|
| - if (*settings != expected_settings)
|
| - return AssertionFailure();
|
| -
|
| - return AssertionSuccess();
|
| -}
|
| -
|
| -DeframerCallbackCollector::DeframerCallbackCollector(
|
| - std::vector<CollectedFrame>* collected_frames)
|
| - : collected_frames_(collected_frames) {
|
| - CHECK(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(SpdyFramer* framer,
|
| - SpdyTestDeframer* deframer) {
|
| - CollectedFrame cf;
|
| - cf.error_reported = true;
|
| - collected_frames_->push_back(std::move(cf));
|
| -}
|
| -
|
| -} // namespace test
|
| -} // namespace net
|
|
|