1 // Classes and utilities for supporting HTTP/2 trace logging, which logs 2 // information about all control and data frames sent and received over 3 // HTTP/2 connections. 4 5 #ifndef QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ 6 #define QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ 7 8 #include <cstdint> 9 10 #include "absl/strings/string_view.h" 11 #include "quiche/common/platform/api/quiche_export.h" 12 #include "quiche/common/platform/api/quiche_logging.h" 13 #include "quiche/common/quiche_callbacks.h" 14 #include "quiche/spdy/core/http2_frame_decoder_adapter.h" 15 #include "quiche/spdy/core/recording_headers_handler.h" 16 #include "quiche/spdy/core/spdy_headers_handler_interface.h" 17 #include "quiche/spdy/core/spdy_protocol.h" 18 19 // Logging macro to use for all HTTP/2 trace logging. Iff trace logging is 20 // enabled, logs at level INFO with a common prefix prepended (to facilitate 21 // post-hoc filtering of trace logging output). 22 #define HTTP2_TRACE_LOG(perspective, is_enabled) \ 23 QUICHE_LOG_IF(INFO, is_enabled()) << "[HTTP2_TRACE " << perspective << "] " 24 25 namespace http2 { 26 27 // Intercepts deframing events to provide detailed logs. Intended to be used for 28 // manual debugging. 29 // 30 // Note any new methods in SpdyFramerVisitorInterface MUST be overridden here to 31 // properly forward the event. This could be ensured by making every event in 32 // SpdyFramerVisitorInterface a pure virtual. 33 class QUICHE_EXPORT Http2TraceLogger : public spdy::SpdyFramerVisitorInterface { 34 public: 35 typedef spdy::SpdyAltSvcWireFormat SpdyAltSvcWireFormat; 36 typedef spdy::SpdyErrorCode SpdyErrorCode; 37 typedef spdy::SpdyFramerVisitorInterface SpdyFramerVisitorInterface; 38 typedef spdy::SpdyPingId SpdyPingId; 39 typedef spdy::SpdyPriority SpdyPriority; 40 typedef spdy::SpdySettingsId SpdySettingsId; 41 typedef spdy::SpdyStreamId SpdyStreamId; 42 43 Http2TraceLogger(SpdyFramerVisitorInterface* parent, 44 absl::string_view perspective, 45 quiche::MultiUseCallback<bool()> is_enabled, 46 const void* connection_id); 47 ~Http2TraceLogger() override; 48 49 Http2TraceLogger(const Http2TraceLogger&) = delete; 50 Http2TraceLogger& operator=(const Http2TraceLogger&) = delete; 51 52 void OnError(http2::Http2DecoderAdapter::SpdyFramerError error, 53 std::string detailed_error) override; 54 void OnCommonHeader(SpdyStreamId stream_id, size_t length, uint8_t type, 55 uint8_t flags) override; 56 spdy::SpdyHeadersHandlerInterface* OnHeaderFrameStart( 57 SpdyStreamId stream_id) override; 58 void OnHeaderFrameEnd(SpdyStreamId stream_id) override; 59 void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, 60 bool fin) override; 61 void OnStreamFrameData(SpdyStreamId stream_id, const char* data, 62 size_t len) override; 63 void OnStreamEnd(SpdyStreamId stream_id) override; 64 void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override; 65 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override; 66 void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override; 67 void OnSetting(spdy::SpdySettingsId id, uint32_t value) override; 68 void OnPing(SpdyPingId unique_id, bool is_ack) override; 69 void OnSettings() override; 70 void OnSettingsEnd() override; 71 void OnSettingsAck() override; 72 void OnGoAway(SpdyStreamId last_accepted_stream_id, 73 SpdyErrorCode error_code) override; 74 bool OnGoAwayFrameData(const char* goaway_data, size_t len) override; 75 void OnHeaders(SpdyStreamId stream_id, size_t payload_length, 76 bool has_priority, int weight, SpdyStreamId parent_stream_id, 77 bool exclusive, bool fin, bool end) override; 78 void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override; 79 void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, 80 bool end) override; 81 void OnContinuation(SpdyStreamId stream_id, size_t payload_length, 82 bool end) override; 83 void OnAltSvc(SpdyStreamId stream_id, absl::string_view origin, 84 const SpdyAltSvcWireFormat::AlternativeServiceVector& 85 altsvc_vector) override; 86 void OnPriority(SpdyStreamId stream_id, SpdyStreamId parent_stream_id, 87 int weight, bool exclusive) override; 88 void OnPriorityUpdate(SpdyStreamId prioritized_stream_id, 89 absl::string_view priority_field_value) override; 90 bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override; 91 void OnUnknownFrameStart(SpdyStreamId stream_id, size_t length, uint8_t type, 92 uint8_t flags) override; 93 void OnUnknownFramePayload(SpdyStreamId stream_id, 94 absl::string_view payload) override; 95 96 private: 97 void LogReceivedHeaders() const; 98 99 std::unique_ptr<spdy::RecordingHeadersHandler> recording_headers_handler_; 100 101 SpdyFramerVisitorInterface* wrapped_; 102 const absl::string_view perspective_; 103 const quiche::MultiUseCallback<bool()> is_enabled_; 104 const void* connection_id_; 105 }; 106 107 // Visitor to log control frames that have been written. 108 class QUICHE_EXPORT Http2FrameLogger : public spdy::SpdyFrameVisitor { 109 public: 110 // This class will preface all of its log messages with the value of 111 // |connection_id| in hexadecimal. Http2FrameLogger(absl::string_view perspective,quiche::MultiUseCallback<bool ()> is_enabled,const void * connection_id)112 Http2FrameLogger(absl::string_view perspective, 113 quiche::MultiUseCallback<bool()> is_enabled, 114 const void* connection_id) 115 : perspective_(perspective), 116 is_enabled_(std::move(is_enabled)), 117 connection_id_(connection_id) {} 118 119 Http2FrameLogger(const Http2FrameLogger&) = delete; 120 Http2FrameLogger& operator=(const Http2FrameLogger&) = delete; 121 122 void VisitRstStream(const spdy::SpdyRstStreamIR& rst_stream) override; 123 void VisitSettings(const spdy::SpdySettingsIR& settings) override; 124 void VisitPing(const spdy::SpdyPingIR& ping) override; 125 void VisitGoAway(const spdy::SpdyGoAwayIR& goaway) override; 126 void VisitHeaders(const spdy::SpdyHeadersIR& headers) override; 127 void VisitWindowUpdate( 128 const spdy::SpdyWindowUpdateIR& window_update) override; 129 void VisitPushPromise(const spdy::SpdyPushPromiseIR& push_promise) override; 130 void VisitContinuation(const spdy::SpdyContinuationIR& continuation) override; 131 void VisitAltSvc(const spdy::SpdyAltSvcIR& altsvc) override; 132 void VisitPriority(const spdy::SpdyPriorityIR& priority) override; 133 void VisitData(const spdy::SpdyDataIR& data) override; 134 void VisitPriorityUpdate( 135 const spdy::SpdyPriorityUpdateIR& priority_update) override; 136 void VisitAcceptCh(const spdy::SpdyAcceptChIR& accept_ch) override; 137 void VisitUnknown(const spdy::SpdyUnknownIR& ir) override; 138 139 private: 140 const absl::string_view perspective_; 141 const quiche::MultiUseCallback<bool()> is_enabled_; 142 const void* connection_id_; 143 }; 144 145 } // namespace http2 146 147 #endif // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_ 148