summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/http2/core/http2_trace_logging.h
blob: e1185bf0e58837f80ed9ed9af69e1d9e580ea0cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 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 "common/platform/api/quiche_export.h"
#include "common/platform/api/quiche_logging.h"
#include "spdy/core/http2_frame_decoder_adapter.h"
#include "spdy/core/recording_headers_handler.h"
#include "spdy/core/spdy_headers_handler_interface.h"
#include "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, 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, 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;

 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_