Automated g4 rollback of changelist 466743774.

*** Reason for rollback ***

Broke //video/live/ingest/rush:rush_ingest_quic_server_test because it somehow has `QuicServer::quic_simple_server_backend_` uninitialized in QuicServer::~QuicServer().  Seems like a usage bug, but I'll rollback and figure it out.

*** Original change description ***

Create QUICHE toy CONNECT proxy server

***

PiperOrigin-RevId: 466782365
diff --git a/build/source_list.bzl b/build/source_list.bzl
index 90dd052..313dea4 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -693,7 +693,6 @@
     "common/platform/api/quiche_file_utils.h",
     "common/platform/api/quiche_system_event_loop.h",
     "quic/platform/api/quic_default_proof_providers.h",
-    "quic/tools/connect_server_backend.h",
     "quic/tools/connect_tunnel.h",
     "quic/tools/fake_proof_verifier.h",
     "quic/tools/quic_backend_response.h",
@@ -718,7 +717,6 @@
 ]
 quiche_tool_support_srcs = [
     "common/platform/api/quiche_file_utils.cc",
-    "quic/tools/connect_server_backend.cc",
     "quic/tools/connect_tunnel.cc",
     "quic/tools/quic_backend_response.cc",
     "quic/tools/quic_client_base.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index 842512d..0c08a73 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -693,7 +693,6 @@
     "src/quiche/common/platform/api/quiche_file_utils.h",
     "src/quiche/common/platform/api/quiche_system_event_loop.h",
     "src/quiche/quic/platform/api/quic_default_proof_providers.h",
-    "src/quiche/quic/tools/connect_server_backend.h",
     "src/quiche/quic/tools/connect_tunnel.h",
     "src/quiche/quic/tools/fake_proof_verifier.h",
     "src/quiche/quic/tools/quic_backend_response.h",
@@ -718,7 +717,6 @@
 ]
 quiche_tool_support_srcs = [
     "src/quiche/common/platform/api/quiche_file_utils.cc",
-    "src/quiche/quic/tools/connect_server_backend.cc",
     "src/quiche/quic/tools/connect_tunnel.cc",
     "src/quiche/quic/tools/quic_backend_response.cc",
     "src/quiche/quic/tools/quic_client_base.cc",
diff --git a/build/source_list.json b/build/source_list.json
index 6d14856..a7fdf5b 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -692,7 +692,6 @@
     "quiche/common/platform/api/quiche_file_utils.h",
     "quiche/common/platform/api/quiche_system_event_loop.h",
     "quiche/quic/platform/api/quic_default_proof_providers.h",
-    "quiche/quic/tools/connect_server_backend.h",
     "quiche/quic/tools/connect_tunnel.h",
     "quiche/quic/tools/fake_proof_verifier.h",
     "quiche/quic/tools/quic_backend_response.h",
@@ -717,7 +716,6 @@
   ],
   "quiche_tool_support_srcs": [
     "quiche/common/platform/api/quiche_file_utils.cc",
-    "quiche/quic/tools/connect_server_backend.cc",
     "quiche/quic/tools/connect_tunnel.cc",
     "quiche/quic/tools/quic_backend_response.cc",
     "quiche/quic/tools/quic_client_base.cc",
diff --git a/quiche/quic/tools/connect_server_backend.cc b/quiche/quic/tools/connect_server_backend.cc
deleted file mode 100644
index baee9c1..0000000
--- a/quiche/quic/tools/connect_server_backend.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2022 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 "quiche/quic/tools/connect_server_backend.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/container/flat_hash_set.h"
-#include "absl/strings/string_view.h"
-#include "quiche/quic/core/io/socket_factory.h"
-#include "quiche/quic/tools/connect_tunnel.h"
-#include "quiche/quic/tools/quic_simple_server_backend.h"
-#include "quiche/common/platform/api/quiche_bug_tracker.h"
-#include "quiche/common/platform/api/quiche_logging.h"
-#include "quiche/spdy/core/http2_header_block.h"
-
-namespace quic {
-
-namespace {
-
-void SendErrorResponse(QuicSimpleServerBackend::RequestHandler* request_handler,
-                       absl::string_view error_code) {
-  spdy::Http2HeaderBlock headers;
-  headers[":status"] = error_code;
-  QuicBackendResponse response;
-  response.set_headers(std::move(headers));
-  request_handler->OnResponseBackendComplete(&response);
-}
-
-}  // namespace
-
-ConnectServerBackend::ConnectServerBackend(
-    std::unique_ptr<QuicSimpleServerBackend> non_connect_backend,
-    absl::flat_hash_set<ConnectTunnel::HostAndPort> acceptable_destinations)
-    : non_connect_backend_(std::move(non_connect_backend)),
-      acceptable_destinations_(std::move(acceptable_destinations)) {
-  QUICHE_DCHECK(non_connect_backend_);
-}
-
-ConnectServerBackend::~ConnectServerBackend() {
-  // Expect all streams to be closed before destroying backend.
-  QUICHE_DCHECK(tunnels_.empty());
-}
-
-bool ConnectServerBackend::InitializeBackend(const std::string&) {
-  return true;
-}
-
-bool ConnectServerBackend::IsBackendInitialized() const { return true; }
-
-void ConnectServerBackend::SetSocketFactory(SocketFactory* socket_factory) {
-  QUICHE_DCHECK_NE(socket_factory_, socket_factory);
-  QUICHE_DCHECK(tunnels_.empty());
-  socket_factory_ = socket_factory;
-}
-
-void ConnectServerBackend::FetchResponseFromBackend(
-    const spdy::Http2HeaderBlock& request_headers,
-    const std::string& request_body, RequestHandler* request_handler) {
-  // Not a CONNECT request, so send to `non_connect_backend_`.
-  non_connect_backend_->FetchResponseFromBackend(request_headers, request_body,
-                                                 request_handler);
-}
-
-void ConnectServerBackend::HandleConnectHeaders(
-    const spdy::Http2HeaderBlock& request_headers,
-    RequestHandler* request_handler) {
-  QUICHE_DCHECK(request_headers.contains(":method") &&
-                request_headers.find(":method")->second == "CONNECT");
-
-  if (!socket_factory_) {
-    QUICHE_BUG(connect_server_backend_no_socket_factory)
-        << "Must set socket factory before ConnectServerBackend receives "
-           "requests.";
-    SendErrorResponse(request_handler, "500");
-    return;
-  }
-
-  if (request_headers.contains(":protocol")) {
-    // Anything other than normal CONNECT not supported.
-    // TODO(ericorth): Add CONNECT-UDP support.
-    non_connect_backend_->HandleConnectHeaders(request_headers,
-                                               request_handler);
-    return;
-  }
-
-  auto [tunnel_it, inserted] = tunnels_.emplace(
-      request_handler->stream_id(),
-      std::make_unique<ConnectTunnel>(request_handler, socket_factory_,
-                                      acceptable_destinations_));
-  QUICHE_DCHECK(inserted);
-
-  tunnel_it->second->OpenTunnel(request_headers);
-}
-
-void ConnectServerBackend::HandleConnectData(absl::string_view data,
-                                             bool data_complete,
-                                             RequestHandler* request_handler) {
-  auto tunnel_it = tunnels_.find(request_handler->stream_id());
-  if (tunnel_it == tunnels_.end()) {
-    // If tunnel not found, perhaps it's something being handled for
-    // non-CONNECT. Possible because this method could be called for anything
-    // with a ":method":"CONNECT" header, but this class does not handle such
-    // requests if they have a ":protocol" header.
-    non_connect_backend_->HandleConnectData(data, data_complete,
-                                            request_handler);
-    return;
-  }
-
-  if (!data.empty()) {
-    tunnel_it->second->SendDataToDestination(data);
-  }
-  if (data_complete) {
-    tunnel_it->second->OnClientStreamClose();
-    tunnels_.erase(tunnel_it);
-  }
-}
-
-void ConnectServerBackend::CloseBackendResponseStream(
-    QuicSimpleServerBackend::RequestHandler* request_handler) {
-  auto tunnel_it = tunnels_.find(request_handler->stream_id());
-  if (tunnel_it != tunnels_.end()) {
-    tunnel_it->second->OnClientStreamClose();
-    tunnels_.erase(tunnel_it);
-  }
-
-  non_connect_backend_->CloseBackendResponseStream(request_handler);
-}
-
-}  // namespace quic
diff --git a/quiche/quic/tools/connect_server_backend.h b/quiche/quic/tools/connect_server_backend.h
deleted file mode 100644
index a1cd843..0000000
--- a/quiche/quic/tools/connect_server_backend.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2022 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_QUIC_CONNECT_PROXY_CONNECT_SERVER_BACKEND_H_
-#define QUICHE_QUIC_CONNECT_PROXY_CONNECT_SERVER_BACKEND_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "absl/container/flat_hash_map.h"
-#include "absl/container/flat_hash_set.h"
-#include "quiche/quic/core/io/socket_factory.h"
-#include "quiche/quic/core/quic_types.h"
-#include "quiche/quic/tools/connect_tunnel.h"
-#include "quiche/quic/tools/quic_simple_server_backend.h"
-
-namespace quic {
-
-// QUIC server backend that handles CONNECT requests. Non-CONNECT requests are
-// delegated to a separate backend.
-class ConnectServerBackend : public QuicSimpleServerBackend {
- public:
-  ConnectServerBackend(
-      std::unique_ptr<QuicSimpleServerBackend> non_connect_backend,
-      absl::flat_hash_set<ConnectTunnel::HostAndPort> acceptable_destinations);
-
-  ConnectServerBackend(const ConnectServerBackend&) = delete;
-  ConnectServerBackend& operator=(const ConnectServerBackend&) = delete;
-
-  ~ConnectServerBackend() override;
-
-  // QuicSimpleServerBackend:
-  bool InitializeBackend(const std::string& backend_url) override;
-  bool IsBackendInitialized() const override;
-  void SetSocketFactory(SocketFactory* socket_factory) override;
-  void FetchResponseFromBackend(const spdy::Http2HeaderBlock& request_headers,
-                                const std::string& request_body,
-                                RequestHandler* request_handler) override;
-  void HandleConnectHeaders(const spdy::Http2HeaderBlock& request_headers,
-                            RequestHandler* request_handler) override;
-  void HandleConnectData(absl::string_view data, bool data_complete,
-                         RequestHandler* request_handler) override;
-  void CloseBackendResponseStream(
-      QuicSimpleServerBackend::RequestHandler* request_handler) override;
-
- private:
-  std::unique_ptr<QuicSimpleServerBackend> non_connect_backend_;
-  const absl::flat_hash_set<ConnectTunnel::HostAndPort>
-      acceptable_destinations_;
-
-  SocketFactory* socket_factory_;  // unowned
-  absl::flat_hash_map<QuicStreamId, std::unique_ptr<ConnectTunnel>> tunnels_;
-};
-
-}  // namespace quic
-
-#endif  // QUICHE_QUIC_CONNECT_PROXY_CONNECT_SERVER_BACKEND_H_
diff --git a/quiche/quic/tools/connect_tunnel.cc b/quiche/quic/tools/connect_tunnel.cc
index ef2a5eb..bd0b66e 100644
--- a/quiche/quic/tools/connect_tunnel.cc
+++ b/quiche/quic/tools/connect_tunnel.cc
@@ -81,8 +81,8 @@
   }
   QUICHE_DCHECK_LE(parsed_port_number, std::numeric_limits<uint16_t>::max());
 
-  return ConnectTunnel::HostAndPort(std::move(hostname),
-                                    static_cast<uint16_t>(parsed_port_number));
+  return std::make_pair(std::move(hostname),
+                        static_cast<uint16_t>(parsed_port_number));
 }
 
 absl::optional<ConnectTunnel::HostAndPort> ValidateHeadersAndGetAuthority(
@@ -114,28 +114,22 @@
   return ValidateAndParseAuthorityString(authority_it->second);
 }
 
-bool ValidateAuthority(const ConnectTunnel::HostAndPort& authority,
-                       const absl::flat_hash_set<ConnectTunnel::HostAndPort>&
-                           acceptable_destinations) {
+bool ValidateAuthority(
+    const ConnectTunnel::HostAndPort& authority,
+    const absl::flat_hash_set<std::pair<std::string, uint16_t>>&
+        acceptable_destinations) {
   if (acceptable_destinations.contains(authority)) {
     return true;
   }
 
   QUICHE_DVLOG(1) << "CONNECT request authority: "
-                  << absl::StrCat(authority.host, ":", authority.port)
+                  << absl::StrCat(authority.first, ":", authority.second)
                   << " is not an acceptable allow-listed destiation ";
   return false;
 }
 
 }  // namespace
 
-ConnectTunnel::HostAndPort::HostAndPort(std::string host, uint16_t port)
-    : host(std::move(host)), port(port) {}
-
-bool ConnectTunnel::HostAndPort::operator==(const HostAndPort& other) const {
-  return host == other.host && port == other.port;
-}
-
 ConnectTunnel::ConnectTunnel(
     QuicSimpleServerBackend::RequestHandler* client_stream_request_handler,
     SocketFactory* socket_factory,
@@ -174,8 +168,9 @@
     return;
   }
 
-  QuicSocketAddress address = tools::LookupAddress(
-      AF_UNSPEC, authority->host, absl::StrCat(authority->port));
+  QuicSocketAddress address =
+      tools::LookupAddress(AF_UNSPEC, authority.value().first,
+                           absl::StrCat(authority.value().second));
   if (!address.IsInitialized()) {
     TerminateClientStream("host resolution error");
     return;
@@ -198,7 +193,7 @@
 
   QUICHE_DVLOG(1) << "CONNECT tunnel opened from stream "
                   << client_stream_request_handler_->stream_id() << " to "
-                  << authority->host << ":" << authority->port;
+                  << authority.value().first << ":" << authority.value().second;
 
   SendConnectResponse();
   BeginAsyncReadFromDestination();
diff --git a/quiche/quic/tools/connect_tunnel.h b/quiche/quic/tools/connect_tunnel.h
index d18d63f..f638324 100644
--- a/quiche/quic/tools/connect_tunnel.h
+++ b/quiche/quic/tools/connect_tunnel.h
@@ -26,19 +26,7 @@
 // Manages a single connection tunneled over a CONNECT proxy.
 class ConnectTunnel : public StreamClientSocket::AsyncVisitor {
  public:
-  struct HostAndPort {
-    HostAndPort(std::string host, uint16_t port);
-
-    bool operator==(const HostAndPort& other) const;
-
-    template <typename H>
-    friend H AbslHashValue(H h, const HostAndPort& host_and_port) {
-      return H::combine(std::move(h), host_and_port.host, host_and_port.port);
-    }
-
-    std::string host;
-    uint16_t port;
-  };
+  using HostAndPort = std::pair<std::string, uint16_t>;
 
   // `client_stream_request_handler` and `socket_factory` must both outlive the
   // created ConnectTunnel.
diff --git a/quiche/quic/tools/quic_server.cc b/quiche/quic/tools/quic_server.cc
index 0c3233a..53985e7 100644
--- a/quiche/quic/tools/quic_server.cc
+++ b/quiche/quic/tools/quic_server.cc
@@ -16,7 +16,6 @@
 
 #include "quiche/quic/core/crypto/crypto_handshake.h"
 #include "quiche/quic/core/crypto/quic_random.h"
-#include "quiche/quic/core/io/event_loop_socket_factory.h"
 #include "quiche/quic/core/io/quic_default_event_loop.h"
 #include "quiche/quic/core/io/quic_event_loop.h"
 #include "quiche/quic/core/quic_clock.h"
@@ -33,7 +32,6 @@
 #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
 #include "quiche/quic/tools/quic_simple_dispatcher.h"
 #include "quiche/quic/tools/quic_simple_server_backend.h"
-#include "quiche/common/simple_buffer_allocator.h"
 
 namespace quic {
 
@@ -105,20 +103,11 @@
 QuicServer::~QuicServer() {
   close(fd_);
   fd_ = -1;
-
-  // Should be fine without because nothing should send requests to the backend
-  // after `this` is destroyed, but for extra pointer safety, clear the socket
-  // factory from the backend before the socket factory is destroyed.
-  quic_simple_server_backend_->SetSocketFactory(nullptr);
 }
 
 bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
   event_loop_ = CreateEventLoop();
 
-  socket_factory_ = std::make_unique<EventLoopSocketFactory>(
-      event_loop_.get(), quiche::SimpleBufferAllocator::Get());
-  quic_simple_server_backend_->SetSocketFactory(socket_factory_.get());
-
   QuicUdpSocketApi socket_api;
   fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
                           /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
diff --git a/quiche/quic/tools/quic_server.h b/quiche/quic/tools/quic_server.h
index d080cb1..7cb870f 100644
--- a/quiche/quic/tools/quic_server.h
+++ b/quiche/quic/tools/quic_server.h
@@ -16,7 +16,6 @@
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/crypto/quic_crypto_server_config.h"
 #include "quiche/quic/core/io/quic_event_loop.h"
-#include "quiche/quic/core/io/socket_factory.h"
 #include "quiche/quic/core/quic_config.h"
 #include "quiche/quic/core/quic_packet_writer.h"
 #include "quiche/quic/core/quic_udp_socket.h"
@@ -115,9 +114,6 @@
 
   // Schedules alarms and notifies the server of the I/O events.
   std::unique_ptr<QuicEventLoop> event_loop_;
-  // Used by some backends to create additional sockets, e.g. for upstream
-  // destination connections for proxying.
-  std::unique_ptr<SocketFactory> socket_factory_;
   // Accepts data from the framer and demuxes clients to sessions.
   std::unique_ptr<QuicDispatcher> dispatcher_;
 
diff --git a/quiche/quic/tools/quic_simple_server_backend.h b/quiche/quic/tools/quic_simple_server_backend.h
index 26eaa65..bbb0d93 100644
--- a/quiche/quic/tools/quic_simple_server_backend.h
+++ b/quiche/quic/tools/quic_simple_server_backend.h
@@ -9,10 +9,10 @@
 #include <memory>
 
 #include "absl/strings/string_view.h"
-#include "quiche/quic/core/io/socket_factory.h"
 #include "quiche/quic/core/quic_error_codes.h"
 #include "quiche/quic/core/quic_types.h"
 #include "quiche/quic/core/web_transport_interface.h"
+#include "quiche/quic/platform/api/quic_logging.h"
 #include "quiche/quic/tools/quic_backend_response.h"
 #include "quiche/spdy/core/http2_header_block.h"
 
@@ -59,10 +59,6 @@
   // Returns true if the backend has been successfully initialized
   // and could be used to fetch HTTP requests
   virtual bool IsBackendInitialized() const = 0;
-  // Passes the socket factory in use by the QuicServer. Must live as long as
-  // incoming requests/data are still sent to the backend, or until cleared by
-  // calling with null. Must not be called while backend is handling requests.
-  virtual void SetSocketFactory(SocketFactory* /*socket_factory*/) {}
   // Triggers a HTTP request to be sent to the backend server or cache
   // If response is immediately available, the function synchronously calls
   // the `request_handler` with the HTTP response.
diff --git a/quiche/quic/tools/quic_toy_server.cc b/quiche/quic/tools/quic_toy_server.cc
index 500e5a1..6b3c76f 100644
--- a/quiche/quic/tools/quic_toy_server.cc
+++ b/quiche/quic/tools/quic_toy_server.cc
@@ -4,20 +4,14 @@
 
 #include "quiche/quic/tools/quic_toy_server.h"
 
-#include <limits>
 #include <utility>
 #include <vector>
 
-#include "absl/strings/str_split.h"
-#include "url/third_party/mozilla/url_parse.h"
 #include "quiche/quic/core/quic_versions.h"
 #include "quiche/quic/platform/api/quic_default_proof_providers.h"
 #include "quiche/quic/platform/api/quic_socket_address.h"
-#include "quiche/quic/tools/connect_server_backend.h"
-#include "quiche/quic/tools/connect_tunnel.h"
 #include "quiche/quic/tools/quic_memory_cache_backend.h"
 #include "quiche/common/platform/api/quiche_command_line_flags.h"
-#include "quiche/common/platform/api/quiche_logging.h"
 
 DEFINE_QUICHE_COMMAND_LINE_FLAG(int32_t, port, 6121,
                                 "The port the quic server will listen on.");
@@ -45,54 +39,8 @@
 DEFINE_QUICHE_COMMAND_LINE_FLAG(bool, enable_webtransport, false,
                                 "If true, WebTransport support is enabled.");
 
-DEFINE_QUICHE_COMMAND_LINE_FLAG(
-    std::string, connect_proxy_destinations, "",
-    "Specifies a comma-separated list of destinations (\"hostname:port\") to "
-    "which the quic server will allow tunneling via CONNECT.");
-
 namespace quic {
 
-namespace {
-
-ConnectTunnel::HostAndPort ParseProxyDestination(
-    absl::string_view destination) {
-  url::Component username_component;
-  url::Component password_component;
-  url::Component host_component;
-  url::Component port_component;
-
-  url::ParseAuthority(destination.data(), url::Component(0, destination.size()),
-                      &username_component, &password_component, &host_component,
-                      &port_component);
-
-  // Only support "host:port"
-  QUICHE_CHECK(!username_component.is_valid() &&
-               !password_component.is_valid());
-  QUICHE_CHECK(host_component.is_nonempty() && port_component.is_nonempty());
-
-  QUICHE_CHECK_LT(static_cast<size_t>(host_component.end()),
-                  destination.size());
-  if (host_component.len > 2 && destination[host_component.begin] == '[' &&
-      destination[host_component.end() - 1] == ']') {
-    // Strip "[]" off IPv6 literals.
-    host_component.begin += 1;
-    host_component.len -= 2;
-  }
-  std::string hostname(destination.data() + host_component.begin,
-                       host_component.len);
-
-  int parsed_port_number = url::ParsePort(destination.data(), port_component);
-
-  // Require specified and valid port.
-  QUICHE_CHECK_GT(parsed_port_number, 0);
-  QUICHE_CHECK_LE(parsed_port_number, std::numeric_limits<uint16_t>::max());
-
-  return ConnectTunnel::HostAndPort(std::move(hostname),
-                                    static_cast<uint16_t>(parsed_port_number));
-}
-
-}  // namespace
-
 std::unique_ptr<quic::QuicSimpleServerBackend>
 QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
   auto memory_cache_backend = std::make_unique<QuicMemoryCacheBackend>();
@@ -107,21 +55,6 @@
   if (quiche::GetQuicheCommandLineFlag(FLAGS_enable_webtransport)) {
     memory_cache_backend->EnableWebTransport();
   }
-
-  if (!quiche::GetQuicheCommandLineFlag(FLAGS_connect_proxy_destinations)
-           .empty()) {
-    absl::flat_hash_set<ConnectTunnel::HostAndPort> connect_proxy_destinations;
-    for (absl::string_view destination : absl::StrSplit(
-             quiche::GetQuicheCommandLineFlag(FLAGS_connect_proxy_destinations),
-             ',', absl::SkipEmpty())) {
-      connect_proxy_destinations.insert(ParseProxyDestination(destination));
-    }
-    QUICHE_CHECK(!connect_proxy_destinations.empty());
-
-    return std::make_unique<ConnectServerBackend>(
-        std::move(memory_cache_backend), std::move(connect_proxy_destinations));
-  }
-
   return memory_cache_backend;
 }