Unify gfe2::RecordingHeadersHandler and spdy::TestHeadersHandler to spdy::RecordingHeadersHandler.

This CL extracts spdy::TestHeadersHandler into its own file and renames to
spdy::RecordingHeadersHandler. Then gfe2::RecordingHeadersHandler is nixed in
favor of spdy::RecordingHeadersHandler. This is a clean-up in its own right.

This CL is also a prefactor for forking http2_trace_logging.{h,cc} to
shinkansen_trace_logging.{h,cc}. It aims to reduce the content in
http2_trace_logging.{h,cc}, to reduce the content to fork.

PiperOrigin-RevId: 341693359
Change-Id: I00740b20a4e95dca9f612fe8a4dc155814a7b84f
diff --git a/quic/core/http/quic_headers_stream_test.cc b/quic/core/http/quic_headers_stream_test.cc
index 44ed080..8f604b3 100644
--- a/quic/core/http/quic_headers_stream_test.cc
+++ b/quic/core/http/quic_headers_stream_test.cc
@@ -28,11 +28,13 @@
 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
 #include "net/third_party/quiche/src/common/quiche_endian.h"
 #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_alt_svc_wire_format.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
 
 using spdy::ERROR_CODE_PROTOCOL_ERROR;
+using spdy::RecordingHeadersHandler;
 using spdy::SETTINGS_ENABLE_PUSH;
 using spdy::SETTINGS_HEADER_TABLE_SIZE;
 using spdy::SETTINGS_INITIAL_WINDOW_SIZE;
@@ -60,7 +62,6 @@
 using spdy::SpdySettingsIR;
 using spdy::SpdyStreamId;
 using spdy::SpdyWindowUpdateIR;
-using spdy::test::TestHeadersHandler;
 using testing::_;
 using testing::AnyNumber;
 using testing::AtLeast;
@@ -294,7 +295,7 @@
   }
 
   void SaveToHandler(size_t size, const QuicHeaderList& header_list) {
-    headers_handler_ = std::make_unique<TestHeadersHandler>();
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
     headers_handler_->OnHeaderBlockStart();
     for (const auto& p : header_list) {
       headers_handler_->OnHeader(p.first, p.second);
@@ -339,7 +340,7 @@
                             /*parent_stream_id=*/0,
                             /*exclusive=*/false, fin, kFrameComplete));
     }
-    headers_handler_ = std::make_unique<TestHeadersHandler>();
+    headers_handler_ = std::make_unique<RecordingHeadersHandler>();
     EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
         .WillOnce(Return(headers_handler_.get()));
     EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
@@ -390,7 +391,7 @@
   StrictMock<MockQuicSpdySession> session_;
   QuicHeadersStream* headers_stream_;
   SpdyHeaderBlock headers_;
-  std::unique_ptr<TestHeadersHandler> headers_handler_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
   std::string body_;
   std::string saved_data_;
   std::string saved_header_data_;
@@ -449,7 +450,7 @@
       // Parse the outgoing data and check that it matches was was written.
       EXPECT_CALL(visitor_,
                   OnPushPromise(stream_id, promised_stream_id, kFrameComplete));
-      headers_handler_ = std::make_unique<TestHeadersHandler>();
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
       EXPECT_CALL(visitor_, OnHeaderFrameStart(stream_id))
           .WillOnce(Return(headers_handler_.get()));
       EXPECT_CALL(visitor_, OnHeaderFrameEnd(stream_id)).Times(1);
diff --git a/spdy/core/hpack/hpack_decoder_adapter_test.cc b/spdy/core/hpack/hpack_decoder_adapter_test.cc
index b1591af..5a69a12 100644
--- a/spdy/core/hpack/hpack_decoder_adapter_test.cc
+++ b/spdy/core/hpack/hpack_decoder_adapter_test.cc
@@ -22,6 +22,7 @@
 #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
 #include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h"
 #include "net/third_party/quiche/src/spdy/core/hpack/hpack_output_stream.h"
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
 #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"
 #include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h"
@@ -178,7 +179,7 @@
         decode_has_failed_ = true;
         return false;
       }
-      total_hpack_bytes = handler_.compressed_header_bytes_parsed();
+      total_hpack_bytes = handler_.compressed_header_bytes();
     } else {
       if (!HandleControlFrameHeadersComplete(&total_hpack_bytes)) {
         decode_has_failed_ = true;
@@ -187,7 +188,8 @@
     }
     EXPECT_EQ(total_hpack_bytes, bytes_passed_in_);
     if (check_decoded_size && start_choice_ == START_WITH_HANDLER) {
-      EXPECT_EQ(handler_.header_bytes_parsed(), SizeOfHeaders(decoded_block()));
+      EXPECT_EQ(handler_.uncompressed_header_bytes(),
+                SizeOfHeaders(decoded_block()));
     }
     return true;
   }
@@ -252,7 +254,7 @@
   http2::test::Http2Random random_;
   HpackDecoderAdapter decoder_;
   test::HpackDecoderAdapterPeer decoder_peer_;
-  TestHeadersHandler handler_;
+  RecordingHeadersHandler handler_;
   StartChoice start_choice_;
   bool randomly_split_input_buffer_;
   bool decode_has_failed_ = false;
@@ -1104,7 +1106,7 @@
   EXPECT_EQ(expected_header_set, decoded_block());
 
   if (start_choice_ == START_WITH_HANDLER) {
-    EXPECT_EQ(handler_.header_bytes_parsed(),
+    EXPECT_EQ(handler_.uncompressed_header_bytes(),
               6 * name.size() + 2 * value1.size() + 2 * value2.size() +
                   2 * value3.size());
   }
diff --git a/spdy/core/mock_spdy_framer_visitor.h b/spdy/core/mock_spdy_framer_visitor.h
index 31ed952..5faf2fb 100644
--- a/spdy/core/mock_spdy_framer_visitor.h
+++ b/spdy/core/mock_spdy_framer_visitor.h
@@ -12,6 +12,7 @@
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
 #include "net/third_party/quiche/src/spdy/core/http2_frame_decoder_adapter.h"
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
 
 namespace spdy {
@@ -117,7 +118,7 @@
   SpdyHeadersHandlerInterface* ReturnTestHeadersHandler(
       SpdyStreamId /* stream_id */) {
     if (headers_handler_ == nullptr) {
-      headers_handler_ = std::make_unique<TestHeadersHandler>();
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
     }
     return headers_handler_.get();
   }
diff --git a/spdy/core/recording_headers_handler.cc b/spdy/core/recording_headers_handler.cc
new file mode 100644
index 0000000..02e5ede
--- /dev/null
+++ b/spdy/core/recording_headers_handler.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
+
+namespace spdy {
+
+RecordingHeadersHandler::RecordingHeadersHandler(
+    SpdyHeadersHandlerInterface* wrapped)
+    : wrapped_(wrapped) {}
+
+void RecordingHeadersHandler::OnHeaderBlockStart() {
+  block_.clear();
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeaderBlockStart();
+  }
+}
+
+void RecordingHeadersHandler::OnHeader(absl::string_view key,
+                                       absl::string_view value) {
+  block_.AppendValueOrAddHeader(key, value);
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeader(key, value);
+  }
+}
+
+void RecordingHeadersHandler::OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                                               size_t compressed_header_bytes) {
+  uncompressed_header_bytes_ = uncompressed_header_bytes;
+  compressed_header_bytes_ = compressed_header_bytes;
+  if (wrapped_ != nullptr) {
+    wrapped_->OnHeaderBlockEnd(uncompressed_header_bytes,
+                               compressed_header_bytes);
+  }
+}
+
+}  // namespace spdy
diff --git a/spdy/core/recording_headers_handler.h b/spdy/core/recording_headers_handler.h
new file mode 100644
index 0000000..a61670e
--- /dev/null
+++ b/spdy/core/recording_headers_handler.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
+#define QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_export.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
+#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h"
+
+namespace spdy {
+
+// RecordingHeadersHandler copies the headers emitted from the deframer, and
+// when needed can forward events to another wrapped handler.
+class QUICHE_EXPORT_PRIVATE RecordingHeadersHandler
+    : public SpdyHeadersHandlerInterface {
+ public:
+  explicit RecordingHeadersHandler(
+      SpdyHeadersHandlerInterface* wrapped = nullptr);
+  RecordingHeadersHandler(const RecordingHeadersHandler&) = delete;
+  RecordingHeadersHandler& operator=(const RecordingHeadersHandler&) = delete;
+
+  void OnHeaderBlockStart() override;
+
+  void OnHeader(absl::string_view key, absl::string_view value) override;
+
+  void OnHeaderBlockEnd(size_t uncompressed_header_bytes,
+                        size_t compressed_header_bytes) override;
+
+  const Http2HeaderBlock& decoded_block() const { return block_; }
+  size_t uncompressed_header_bytes() const {
+    return uncompressed_header_bytes_;
+  }
+  size_t compressed_header_bytes() const { return compressed_header_bytes_; }
+
+ private:
+  SpdyHeadersHandlerInterface* wrapped_ = nullptr;
+  Http2HeaderBlock block_;
+  size_t uncompressed_header_bytes_ = 0;
+  size_t compressed_header_bytes_ = 0;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_CORE_RECORDING_HEADERS_HANDLER_H_
diff --git a/spdy/core/spdy_deframer_visitor.cc b/spdy/core/spdy_deframer_visitor.cc
index f5d3646..835fea9 100644
--- a/spdy/core/spdy_deframer_visitor.cc
+++ b/spdy/core/spdy_deframer_visitor.cc
@@ -15,6 +15,7 @@
 #include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
 #include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
 #include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
@@ -226,7 +227,7 @@
   std::unique_ptr<std::string> goaway_description_;
   std::unique_ptr<StringPairVector> headers_;
   std::unique_ptr<SettingVector> settings_;
-  std::unique_ptr<TestHeadersHandler> headers_handler_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
 
   std::unique_ptr<SpdyGoAwayIR> goaway_ir_;
   std::unique_ptr<SpdyHeadersIR> headers_ir_;
@@ -531,7 +532,7 @@
   end_ = end;
 
   headers_ = std::make_unique<StringPairVector>();
-  headers_handler_ = std::make_unique<TestHeadersHandler>();
+  headers_handler_ = std::make_unique<RecordingHeadersHandler>();
   headers_ir_ = std::make_unique<SpdyHeadersIR>(stream_id);
   headers_ir_->set_fin(fin);
   if (has_priority) {
@@ -587,7 +588,7 @@
   end_ = end;
 
   headers_ = std::make_unique<StringPairVector>();
-  headers_handler_ = std::make_unique<TestHeadersHandler>();
+  headers_handler_ = std::make_unique<RecordingHeadersHandler>();
   push_promise_ir_ =
       std::make_unique<SpdyPushPromiseIR>(stream_id, promised_stream_id);
 }
diff --git a/spdy/core/spdy_framer_test.cc b/spdy/core/spdy_framer_test.cc
index 3ddaec5..6a14d0c 100644
--- a/spdy/core/spdy_framer_test.cc
+++ b/spdy/core/spdy_framer_test.cc
@@ -17,6 +17,7 @@
 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
 #include "net/third_party/quiche/src/spdy/core/array_output_buffer.h"
 #include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
+#include "net/third_party/quiche/src/spdy/core/recording_headers_handler.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_bitmasks.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
@@ -315,7 +316,7 @@
   SpdyHeadersHandlerInterface* OnHeaderFrameStart(
       SpdyStreamId /*stream_id*/) override {
     if (headers_handler_ == nullptr) {
-      headers_handler_ = std::make_unique<TestHeadersHandler>();
+      headers_handler_ = std::make_unique<RecordingHeadersHandler>();
     }
     return headers_handler_.get();
   }
@@ -323,7 +324,7 @@
   void OnHeaderFrameEnd(SpdyStreamId /*stream_id*/) override {
     CHECK(headers_handler_ != nullptr);
     headers_ = headers_handler_->decoded_block().Clone();
-    header_bytes_received_ = headers_handler_->header_bytes_parsed();
+    header_bytes_received_ = headers_handler_->uncompressed_header_bytes();
     headers_handler_.reset();
   }
 
@@ -531,7 +532,7 @@
   SpdyStreamId header_stream_id_;
   SpdyFrameType header_control_type_;
   bool header_buffer_valid_;
-  std::unique_ptr<TestHeadersHandler> headers_handler_;
+  std::unique_ptr<RecordingHeadersHandler> headers_handler_;
   Http2HeaderBlock headers_;
   bool header_has_priority_;
   SpdyStreamId header_parent_stream_id_;
diff --git a/spdy/core/spdy_test_utils.cc b/spdy/core/spdy_test_utils.cc
index 6eb15ec..5372bcd 100644
--- a/spdy/core/spdy_test_utils.cc
+++ b/spdy/core/spdy_test_utils.cc
@@ -100,21 +100,5 @@
   }
 }
 
-void TestHeadersHandler::OnHeaderBlockStart() {
-  block_.clear();
-}
-
-void TestHeadersHandler::OnHeader(absl::string_view name,
-                                  absl::string_view value) {
-  block_.AppendValueOrAddHeader(name, value);
-}
-
-void TestHeadersHandler::OnHeaderBlockEnd(
-    size_t header_bytes_parsed,
-    size_t compressed_header_bytes_parsed) {
-  header_bytes_parsed_ = header_bytes_parsed;
-  compressed_header_bytes_parsed_ = compressed_header_bytes_parsed;
-}
-
 }  // namespace test
 }  // namespace spdy
diff --git a/spdy/core/spdy_test_utils.h b/spdy/core/spdy_test_utils.h
index c6390a7..920838e 100644
--- a/spdy/core/spdy_test_utils.h
+++ b/spdy/core/spdy_test_utils.h
@@ -11,9 +11,7 @@
 
 #include "absl/strings/string_view.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h"
-#include "net/third_party/quiche/src/spdy/core/spdy_headers_handler_interface.h"
 #include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
-#include "net/third_party/quiche/src/spdy/platform/api/spdy_bug_tracker.h"
 
 namespace spdy {
 
@@ -39,33 +37,6 @@
 
 void SetFrameLength(SpdySerializedFrame* frame, size_t length);
 
-// A test implementation of SpdyHeadersHandlerInterface that correctly
-// reconstructs multiple header values for the same name.
-class TestHeadersHandler : public SpdyHeadersHandlerInterface {
- public:
-  TestHeadersHandler() {}
-  TestHeadersHandler(const TestHeadersHandler&) = delete;
-  TestHeadersHandler& operator=(const TestHeadersHandler&) = delete;
-
-  void OnHeaderBlockStart() override;
-
-  void OnHeader(absl::string_view name, absl::string_view value) override;
-
-  void OnHeaderBlockEnd(size_t header_bytes_parsed,
-                        size_t compressed_header_bytes_parsed) override;
-
-  const Http2HeaderBlock& decoded_block() const { return block_; }
-  size_t header_bytes_parsed() const { return header_bytes_parsed_; }
-  size_t compressed_header_bytes_parsed() const {
-    return compressed_header_bytes_parsed_;
-  }
-
- private:
-  Http2HeaderBlock block_;
-  size_t header_bytes_parsed_ = 0;
-  size_t compressed_header_bytes_parsed_ = 0;
-};
-
 }  // namespace test
 }  // namespace spdy