| // Classes and utilities for supporting HTTP/2 trace logging, which logs | |
| // information about all control and data frames sent and received over | |
| // HTTP/2 connections. | |
| #ifndef QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ | |
| #define QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ | |
| #include <cstdint> | |
| #include "absl/strings/string_view.h" | |
| #include "quiche/common/platform/api/quiche_export.h" | |
| #include "quiche/common/platform/api/quiche_logging.h" | |
| #include "quiche/spdy/core/http2_frame_decoder_adapter.h" | |
| #include "quiche/spdy/core/recording_headers_handler.h" | |
| #include "quiche/spdy/core/spdy_headers_handler_interface.h" | |
| #include "quiche/spdy/core/spdy_protocol.h" | |
| // Logging macro to use for all HTTP/2 trace logging. Iff trace logging is | |
| // enabled, logs at level INFO with a common prefix prepended (to facilitate | |
| // post-hoc filtering of trace logging output). | |
| #define HTTP2_TRACE_LOG(perspective, is_enabled) \ | |
| QUICHE_LOG_IF(INFO, is_enabled()) << "[HTTP2_TRACE " << perspective << "] " | |
| namespace http2 { | |
| // Intercepts deframing events to provide detailed logs. Intended to be used for | |
| // manual debugging. | |
| // | |
| // Note any new methods in SpdyFramerVisitorInterface MUST be overridden here to | |
| // properly forward the event. This could be ensured by making every event in | |
| // SpdyFramerVisitorInterface a pure virtual. | |
| class QUICHE_EXPORT_PRIVATE Http2TraceLogger | |
| : public spdy::SpdyFramerVisitorInterface { | |
| public: | |
| typedef spdy::SpdyAltSvcWireFormat SpdyAltSvcWireFormat; | |
| typedef spdy::SpdyErrorCode SpdyErrorCode; | |
| typedef spdy::SpdyFramerVisitorInterface SpdyFramerVisitorInterface; | |
| typedef spdy::SpdyPingId SpdyPingId; | |
| typedef spdy::SpdyPriority SpdyPriority; | |
| typedef spdy::SpdySettingsId SpdySettingsId; | |
| typedef spdy::SpdyStreamId SpdyStreamId; | |
| Http2TraceLogger(SpdyFramerVisitorInterface* parent, | |
| absl::string_view perspective, | |
| std::function<bool()> is_enabled, const void* connection_id); | |
| ~Http2TraceLogger() override; | |
| Http2TraceLogger(const Http2TraceLogger&) = delete; | |
| Http2TraceLogger& operator=(const Http2TraceLogger&) = delete; | |
| void OnError(http2::Http2DecoderAdapter::SpdyFramerError error, | |
| std::string detailed_error) override; | |
| void OnCommonHeader(SpdyStreamId stream_id, size_t length, uint8_t type, | |
| uint8_t flags) override; | |
| spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart( | |
| SpdyStreamId stream_id) override; | |
| void OnHeaderFrameEnd(SpdyStreamId stream_id) override; | |
| void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, | |
| bool fin) 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; | |
| void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override; | |
| void OnSetting(spdy::SpdySettingsId id, uint32_t value) override; | |
| void OnPing(SpdyPingId unique_id, bool is_ack) override; | |
| void OnSettings() override; | |
| void OnSettingsEnd() override; | |
| void OnSettingsAck() 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, size_t payload_length, | |
| bool has_priority, int weight, SpdyStreamId parent_stream_id, | |
| bool exclusive, bool fin, bool end) override; | |
| void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override; | |
| void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, | |
| bool end) override; | |
| void OnContinuation(SpdyStreamId stream_id, size_t payload_length, | |
| bool end) override; | |
| void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin, | |
| const SpdyAltSvcWireFormat::AlternativeServiceVector& | |
| altsvc_vector) override; | |
| void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id, | |
| int weight, bool exclusive) override; | |
| void OnPriorityUpdate(SpdyStreamId prioritized_stream_id, | |
| absl::string_view priority_field_value) override; | |
| bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override; | |
| void OnUnknownFrameStart(SpdyStreamId stream_id, size_t length, uint8_t type, | |
| uint8_t flags) override; | |
| void OnUnknownFramePayload(SpdyStreamId stream_id, | |
| absl::string_view payload) override; | |
| private: | |
| void LogReceivedHeaders() const; | |
| std::unique_ptr<spdy::RecordingHeadersHandler> recording_headers_handler_; | |
| SpdyFramerVisitorInterface* wrapped_; | |
| const absl::string_view perspective_; | |
| const std::function<bool()> is_enabled_; | |
| const void* connection_id_; | |
| }; | |
| // Visitor to log control frames that have been written. | |
| class QUICHE_EXPORT_PRIVATE Http2FrameLogger : public spdy::SpdyFrameVisitor { | |
| public: | |
| // This class will preface all of its log messages with the value of | |
| // |connection_id| in hexadecimal. | |
| Http2FrameLogger(absl::string_view perspective, | |
| std::function<bool()> is_enabled, const void* connection_id) | |
| : perspective_(perspective), | |
| is_enabled_(std::move(is_enabled)), | |
| connection_id_(connection_id) {} | |
| Http2FrameLogger(const Http2FrameLogger&) = delete; | |
| Http2FrameLogger& operator=(const Http2FrameLogger&) = delete; | |
| void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override; | |
| void VisitSettings(const spdy::SpdySettingsIR& settings) override; | |
| void VisitPing(const spdy::SpdyPingIR& ping) override; | |
| void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override; | |
| void VisitHeaders(const spdy::SpdyHeadersIR& headers) override; | |
| void VisitWindowUpdate( | |
| const spdy::SpdyWindowUpdateIR& window_update) override; | |
| void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override; | |
| void VisitContinuation(const spdy::SpdyContinuationIR& continuation) override; | |
| void VisitAltSvc(const spdy::SpdyAltSvcIR& altsvc) override; | |
| void VisitPriority(const spdy::SpdyPriorityIR& priority) override; | |
| void VisitData(const spdy::SpdyDataIR& data) override; | |
| void VisitPriorityUpdate( | |
| const spdy::SpdyPriorityUpdateIR& priority_update) override; | |
| void VisitAcceptCh(const spdy::SpdyAcceptChIR& accept_ch) override; | |
| void VisitUnknown(const spdy::SpdyUnknownIR& ir) override; | |
| private: | |
| const absl::string_view perspective_; | |
| const std::function<bool()> is_enabled_; | |
| const void* connection_id_; | |
| }; | |
| } // namespace http2 | |
| #endif // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ |