| #include "quiche/http2/test_tools/http2_trace_printer.h" | |
| #include <algorithm> | |
| #include <cstddef> | |
| #include "absl/strings/escaping.h" | |
| #include "absl/strings/match.h" | |
| #include "absl/strings/string_view.h" | |
| #include "quiche/http2/core/http2_trace_logging.h" | |
| #include "quiche/http2/core/spdy_protocol.h" | |
| namespace http2 { | |
| namespace test { | |
| namespace { | |
| bool IsLoggingEnabled() { return true; } | |
| } // namespace | |
| Http2TracePrinter::Http2TracePrinter(absl::string_view perspective, | |
| const void* connection_id, | |
| bool consume_connection_preface) | |
| : logger_(&visitor_, perspective, IsLoggingEnabled, connection_id), | |
| perspective_(perspective) { | |
| decoder_.set_visitor(&logger_); | |
| if (consume_connection_preface) { | |
| remaining_preface_ = | |
| absl::string_view(spdy::kHttp2ConnectionHeaderPrefix, | |
| spdy::kHttp2ConnectionHeaderPrefixSize); | |
| } | |
| } | |
| void Http2TracePrinter::ProcessInput(absl::string_view bytes) { | |
| if (preface_error_) { | |
| HTTP2_TRACE_LOG(perspective_, IsLoggingEnabled) | |
| << "Earlier connection preface error, ignoring " << bytes.size() | |
| << " bytes"; | |
| return; | |
| } | |
| if (!remaining_preface_.empty()) { | |
| const size_t consumed = std::min(remaining_preface_.size(), bytes.size()); | |
| const absl::string_view preface = bytes.substr(0, consumed); | |
| HTTP2_TRACE_LOG(perspective_, IsLoggingEnabled) | |
| << "Received connection preface: " << absl::CEscape(preface); | |
| if (!absl::StartsWith(remaining_preface_, preface)) { | |
| HTTP2_TRACE_LOG(perspective_, IsLoggingEnabled) | |
| << "Received preface does not match expected remaining preface: " | |
| << absl::CEscape(remaining_preface_); | |
| preface_error_ = true; | |
| return; | |
| } | |
| bytes.remove_prefix(consumed); | |
| remaining_preface_.remove_prefix(consumed); | |
| } | |
| decoder_.ProcessInput(bytes.data(), bytes.size()); | |
| } | |
| } // namespace test | |
| } // namespace http2 |