| // Copyright (c) 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_framer_decoder_adapter.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include "base/format_macros.h" |
| #include "base/logging.h" |
| #include "base/strings/stringprintf.h" |
| |
| #if defined(COMPILER_GCC) |
| #define PRETTY_THIS base::StringPrintf("%s@%p ", __PRETTY_FUNCTION__, this) |
| #elif defined(COMPILER_MSVC) |
| #define PRETTY_THIS base::StringPrintf("%s@%p ", __FUNCSIG__, this) |
| #else |
| #define PRETTY_THIS base::StringPrintf("%s@%p ", __func__, this) |
| #endif |
| |
| namespace net { |
| |
| SpdyFramerDecoderAdapter::SpdyFramerDecoderAdapter() { |
| DVLOG(1) << PRETTY_THIS; |
| } |
| |
| SpdyFramerDecoderAdapter::~SpdyFramerDecoderAdapter() { |
| DVLOG(1) << PRETTY_THIS; |
| } |
| |
| void SpdyFramerDecoderAdapter::set_visitor( |
| SpdyFramerVisitorInterface* visitor) { |
| visitor_ = visitor; |
| } |
| |
| void SpdyFramerDecoderAdapter::set_debug_visitor( |
| SpdyFramerDebugVisitorInterface* debug_visitor) { |
| debug_visitor_ = debug_visitor; |
| } |
| |
| void SpdyFramerDecoderAdapter::set_process_single_input_frame(bool v) { |
| process_single_input_frame_ = v; |
| } |
| |
| void SpdyFramerVisitorAdapter::OnError(SpdyFramer* framer) { |
| visitor_->OnError(framer_); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnDataFrameHeader(SpdyStreamId stream_id, |
| size_t length, |
| bool fin) { |
| visitor_->OnDataFrameHeader(stream_id, length, fin); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnStreamFrameData(SpdyStreamId stream_id, |
| const char* data, |
| size_t len) { |
| visitor_->OnStreamFrameData(stream_id, data, len); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnStreamEnd(SpdyStreamId stream_id) { |
| visitor_->OnStreamEnd(stream_id); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnStreamPadding(SpdyStreamId stream_id, |
| size_t len) { |
| visitor_->OnStreamPadding(stream_id, len); |
| } |
| |
| SpdyHeadersHandlerInterface* SpdyFramerVisitorAdapter::OnHeaderFrameStart( |
| SpdyStreamId stream_id) { |
| return visitor_->OnHeaderFrameStart(stream_id); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnHeaderFrameEnd(SpdyStreamId stream_id, |
| bool end_headers) { |
| visitor_->OnHeaderFrameEnd(stream_id, end_headers); |
| } |
| |
| bool SpdyFramerVisitorAdapter::OnControlFrameHeaderData( |
| SpdyStreamId stream_id, |
| const char* header_data, |
| size_t header_data_len) { |
| return visitor_->OnControlFrameHeaderData(stream_id, header_data, |
| header_data_len); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSynStream(SpdyStreamId stream_id, |
| SpdyStreamId associated_stream_id, |
| SpdyPriority priority, |
| bool fin, |
| bool unidirectional) { |
| visitor_->OnSynStream(stream_id, associated_stream_id, priority, fin, |
| unidirectional); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSynReply(SpdyStreamId stream_id, bool fin) { |
| visitor_->OnSynReply(stream_id, fin); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnRstStream(SpdyStreamId stream_id, |
| SpdyRstStreamStatus status) { |
| visitor_->OnRstStream(stream_id, status); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSetting(SpdySettingsIds id, |
| uint8_t flags, |
| uint32_t value) { |
| visitor_->OnSetting(id, flags, value); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnPing(SpdyPingId unique_id, bool is_ack) { |
| visitor_->OnPing(unique_id, is_ack); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSettings(bool clear_persisted) { |
| visitor_->OnSettings(clear_persisted); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSettingsAck() { |
| visitor_->OnSettingsAck(); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnSettingsEnd() { |
| visitor_->OnSettingsEnd(); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnGoAway(SpdyStreamId last_accepted_stream_id, |
| SpdyGoAwayStatus status) { |
| visitor_->OnGoAway(last_accepted_stream_id, status); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnHeaders(SpdyStreamId stream_id, |
| bool has_priority, |
| int weight, |
| SpdyStreamId parent_stream_id, |
| bool exclusive, |
| bool fin, |
| bool end) { |
| visitor_->OnHeaders(stream_id, has_priority, weight, parent_stream_id, |
| exclusive, fin, end); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnWindowUpdate(SpdyStreamId stream_id, |
| int delta_window_size) { |
| visitor_->OnWindowUpdate(stream_id, delta_window_size); |
| } |
| |
| bool SpdyFramerVisitorAdapter::OnGoAwayFrameData(const char* goaway_data, |
| size_t len) { |
| return visitor_->OnGoAwayFrameData(goaway_data, len); |
| } |
| |
| bool SpdyFramerVisitorAdapter::OnRstStreamFrameData(const char* rst_stream_data, |
| size_t len) { |
| return visitor_->OnRstStreamFrameData(rst_stream_data, len); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnBlocked(SpdyStreamId stream_id) { |
| visitor_->OnBlocked(stream_id); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnPushPromise(SpdyStreamId stream_id, |
| SpdyStreamId promised_stream_id, |
| bool end) { |
| visitor_->OnPushPromise(stream_id, promised_stream_id, end); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnContinuation(SpdyStreamId stream_id, |
| bool end) { |
| visitor_->OnContinuation(stream_id, end); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnPriority(SpdyStreamId stream_id, |
| SpdyStreamId parent_id, |
| int weight, |
| bool exclusive) { |
| visitor_->OnPriority(stream_id, parent_id, weight, exclusive); |
| } |
| |
| void SpdyFramerVisitorAdapter::OnAltSvc( |
| SpdyStreamId stream_id, |
| base::StringPiece origin, |
| const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) { |
| visitor_->OnAltSvc(stream_id, origin, altsvc_vector); |
| } |
| |
| bool SpdyFramerVisitorAdapter::OnUnknownFrame(SpdyStreamId stream_id, |
| int frame_type) { |
| return visitor_->OnUnknownFrame(stream_id, frame_type); |
| } |
| |
| class NestedSpdyFramerDecoder : public SpdyFramerDecoderAdapter { |
| typedef SpdyFramer::SpdyState SpdyState; |
| typedef SpdyFramer::SpdyError SpdyError; |
| |
| public: |
| explicit NestedSpdyFramerDecoder(SpdyFramer* outer) |
| : framer_(HTTP2, nullptr), outer_(outer) { |
| DVLOG(1) << PRETTY_THIS; |
| } |
| ~NestedSpdyFramerDecoder() override { DVLOG(1) << PRETTY_THIS; } |
| |
| // Wrap the visitor in a SpdyFramerVisitorAdapter so that the correct |
| // SpdyFramer instance is passed to OnError. Passes the call on to the |
| // base adapter class and wrapped SpdyFramer. |
| void set_visitor(SpdyFramerVisitorInterface* visitor) override { |
| visitor_adapter_.reset(new SpdyFramerVisitorAdapter(visitor, outer_)); |
| SpdyFramerDecoderAdapter::set_visitor(visitor_adapter_.get()); |
| framer_.set_visitor(visitor_adapter_.get()); |
| } |
| |
| // Passes the call on to the base adapter class and wrapped SpdyFramer. |
| void set_debug_visitor( |
| SpdyFramerDebugVisitorInterface* debug_visitor) override { |
| SpdyFramerDecoderAdapter::set_debug_visitor(debug_visitor); |
| framer_.set_debug_visitor(debug_visitor); |
| } |
| |
| // Passes the call on to the wrapped SpdyFramer. |
| void SetDecoderHeaderTableDebugVisitor( |
| std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) |
| override { |
| framer_.SetDecoderHeaderTableDebugVisitor(std::move(visitor)); |
| } |
| |
| // Passes the call on to the base adapter class and wrapped SpdyFramer. |
| void set_process_single_input_frame(bool v) override { |
| SpdyFramerDecoderAdapter::set_process_single_input_frame(v); |
| framer_.set_process_single_input_frame(v); |
| } |
| |
| size_t ProcessInput(const char* data, size_t len) override { |
| DVLOG(2) << "ProcessInput(data, " << len << ")"; |
| const bool use_new_methods = outer_->use_new_methods_for_test(); |
| if (framer_.use_new_methods_for_test() != use_new_methods) { |
| DVLOG(1) << "Overriding use_new_methods_ in nested framer, setting=" |
| << (use_new_methods ? "true" : "false"); |
| framer_.set_use_new_methods_for_test(use_new_methods); |
| } |
| size_t result = framer_.ProcessInput(data, len); |
| DVLOG(2) << "ProcessInput(data, " << len << ") returning " << result; |
| return result; |
| } |
| |
| void Reset() override { framer_.Reset(); } |
| |
| SpdyFramer::SpdyError error_code() const override { |
| return framer_.error_code(); |
| } |
| SpdyFramer::SpdyState state() const override { return framer_.state(); } |
| bool probable_http_response() const override { |
| return framer_.probable_http_response(); |
| } |
| |
| private: |
| SpdyFramer framer_; |
| SpdyFramer* const outer_; |
| std::unique_ptr<SpdyFramerVisitorAdapter> visitor_adapter_; |
| }; |
| |
| std::unique_ptr<SpdyFramerDecoderAdapter> CreateNestedSpdyFramerDecoder( |
| SpdyFramer* outer) { |
| return std::unique_ptr<SpdyFramerDecoderAdapter>( |
| new NestedSpdyFramerDecoder(outer)); |
| } |
| |
| } // namespace net |