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