blob: 7106a72e4a58c8a121006c34563142a7edaecb1f [file] [log] [blame]
// 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/common/quiche_callbacks.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 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,
quiche::MultiUseCallback<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 quiche::MultiUseCallback<bool()> is_enabled_;
const void* connection_id_;
};
// Visitor to log control frames that have been written.
class QUICHE_EXPORT 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,
quiche::MultiUseCallback<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 quiche::MultiUseCallback<bool()> is_enabled_;
const void* connection_id_;
};
} // namespace http2
#endif // QUICHE_HTTP2_CORE_HTTP2_TRACE_LOGGING_H_