Move virtually all the toy server logic out of quic_server_bin.cc and into a new
QuicToyServer class which can be used in chromium.

gfe-relnote: n/a - Tools only.
PiperOrigin-RevId: 248801380
Change-Id: I5586c13ae6f481564b08140e9c5365d447ac0be1
diff --git a/quic/tools/quic_server.cc b/quic/tools/quic_server.cc
index 5542008..4ac1dac 100644
--- a/quic/tools/quic_server.cc
+++ b/quic/tools/quic_server.cc
@@ -162,6 +162,12 @@
       quic_simple_server_backend_, expected_connection_id_length_);
 }
 
+void QuicServer::HandleEventsForever() {
+  while (true) {
+    WaitForEvents();
+  }
+}
+
 void QuicServer::WaitForEvents() {
   epoll_server_.WaitForEventsAndExecuteCallbacks();
 }
diff --git a/quic/tools/quic_server.h b/quic/tools/quic_server.h
index 4d7e081..6fb1646 100644
--- a/quic/tools/quic_server.h
+++ b/quic/tools/quic_server.h
@@ -22,6 +22,7 @@
 #include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
 #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h"
 
 namespace quic {
 
@@ -32,7 +33,8 @@
 class QuicDispatcher;
 class QuicPacketReader;
 
-class QuicServer : public QuicEpollCallbackInterface {
+class QuicServer : public QuicSpdyServerBase,
+                   public QuicEpollCallbackInterface {
  public:
   QuicServer(std::unique_ptr<ProofSource> proof_source,
              QuicSimpleServerBackend* quic_simple_server_backend);
@@ -50,7 +52,9 @@
   std::string Name() const override { return "QuicServer"; }
 
   // Start listening on the specified address.
-  bool CreateUDPSocketAndListen(const QuicSocketAddress& address);
+  bool CreateUDPSocketAndListen(const QuicSocketAddress& address) override;
+  // Handles all events. Does not return.
+  void HandleEventsForever() override;
 
   // Wait up to 50ms, and handle any events which occur.
   void WaitForEvents();
diff --git a/quic/tools/quic_server_bin.cc b/quic/tools/quic_server_bin.cc
index 128c873..bd13913 100644
--- a/quic/tools/quic_server_bin.cc
+++ b/quic/tools/quic_server_bin.cc
@@ -8,31 +8,21 @@
 #include <vector>
 
 #include "net/third_party/quiche/src/quic/core/quic_versions.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
-#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
-#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
 #include "net/third_party/quiche/src/quic/tools/quic_server.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_toy_server.h"
 
-DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
-                              port,
-                              6121,
-                              "The port the quic server will listen on.");
-
-DEFINE_QUIC_COMMAND_LINE_FLAG(
-    std::string,
-    quic_response_cache_dir,
-    "",
-    "Specifies the directory used during QuicHttpResponseCache "
-    "construction to seed the cache. Cache directory can be "
-    "generated using `wget -p --save-headers <url>`");
-
-DEFINE_QUIC_COMMAND_LINE_FLAG(
-    int32_t,
-    quic_ietf_draft,
-    0,
-    "QUIC IETF draft number to use over the wire, e.g. 18. "
-    "This also enables required internal QUIC flags.");
+class SimpleServerFactory : public quic::QuicToyServer::ServerFactory {
+ public:
+  std::unique_ptr<quic::QuicSpdyServerBase> CreateServer(
+      quic::QuicSimpleServerBackend* backend,
+      std::unique_ptr<quic::ProofSource> proof_source) override {
+    return quic::QuicMakeUnique<quic::QuicServer>(std::move(proof_source),
+                                                  backend);
+  }
+};
 
 int main(int argc, char* argv[]) {
   const char* usage = "Usage: quic_server [options]";
@@ -43,28 +33,8 @@
     exit(0);
   }
 
-  const int32_t quic_ietf_draft = GetQuicFlag(FLAGS_quic_ietf_draft);
-  if (quic_ietf_draft > 0) {
-    quic::QuicVersionInitializeSupportForIetfDraft(quic_ietf_draft);
-    quic::QuicEnableVersion(
-        quic::ParsedQuicVersion(quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_99));
-  }
-
-  quic::QuicMemoryCacheBackend memory_cache_backend;
-  if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
-    memory_cache_backend.InitializeBackend(
-        GetQuicFlag(FLAGS_quic_response_cache_dir));
-  }
-
-  quic::QuicServer server(quic::CreateDefaultProofSource(),
-                          &memory_cache_backend);
-
-  if (!server.CreateUDPSocketAndListen(quic::QuicSocketAddress(
-          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
-    return 1;
-  }
-
-  while (true) {
-    server.WaitForEvents();
-  }
+  quic::QuicToyServer::MemoryCacheBackendFactory backend_factory;
+  SimpleServerFactory server_factory;
+  quic::QuicToyServer server(&backend_factory, &server_factory);
+  return server.Start();
 }
diff --git a/quic/tools/quic_spdy_server_base.h b/quic/tools/quic_spdy_server_base.h
new file mode 100644
index 0000000..1130cfc
--- /dev/null
+++ b/quic/tools/quic_spdy_server_base.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 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.
+
+// A toy server, which connects to a specified port and sends QUIC
+// requests to that endpoint.
+
+#ifndef QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
+#define QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+// Base class for service instances to be used with QuicToyServer.
+class QuicSpdyServerBase {
+ public:
+  virtual ~QuicSpdyServerBase() = default;
+
+  // Creates a UDP socket and listens on |address|. Returns true on success
+  // and false otherwise.
+  virtual bool CreateUDPSocketAndListen(const QuicSocketAddress& address) = 0;
+
+  // Handles incoming requests. Does not return.
+  virtual void HandleEventsForever() = 0;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_SPDY_SERVER_BASE_H_
diff --git a/quic/tools/quic_toy_server.cc b/quic/tools/quic_toy_server.cc
new file mode 100644
index 0000000..633b465
--- /dev/null
+++ b/quic/tools/quic_toy_server.cc
@@ -0,0 +1,73 @@
+// Copyright 2014 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/quic/tools/quic_toy_server.h"
+
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_default_proof_providers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/tools/quic_memory_cache_backend.h"
+
+DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
+                              port,
+                              6121,
+                              "The port the quic server will listen on.");
+
+DEFINE_QUIC_COMMAND_LINE_FLAG(
+    std::string,
+    quic_response_cache_dir,
+    "",
+    "Specifies the directory used during QuicHttpResponseCache "
+    "construction to seed the cache. Cache directory can be "
+    "generated using `wget -p --save-headers <url>`");
+
+DEFINE_QUIC_COMMAND_LINE_FLAG(
+    int32_t,
+    quic_ietf_draft,
+    0,
+    "QUIC IETF draft number to use over the wire, e.g. 18. "
+    "This also enables required internal QUIC flags.");
+
+namespace quic {
+
+std::unique_ptr<quic::QuicSimpleServerBackend>
+QuicToyServer::MemoryCacheBackendFactory::CreateBackend() {
+  auto memory_cache_backend = QuicMakeUnique<QuicMemoryCacheBackend>();
+  if (!GetQuicFlag(FLAGS_quic_response_cache_dir).empty()) {
+    memory_cache_backend->InitializeBackend(
+        GetQuicFlag(FLAGS_quic_response_cache_dir));
+  }
+  return memory_cache_backend;
+}
+
+QuicToyServer::QuicToyServer(BackendFactory* backend_factory,
+                             ServerFactory* server_factory)
+    : backend_factory_(backend_factory), server_factory_(server_factory) {}
+
+int QuicToyServer::Start() {
+  const int32_t quic_ietf_draft = GetQuicFlag(FLAGS_quic_ietf_draft);
+  if (quic_ietf_draft > 0) {
+    quic::QuicVersionInitializeSupportForIetfDraft(quic_ietf_draft);
+    quic::QuicEnableVersion(
+        quic::ParsedQuicVersion(quic::PROTOCOL_TLS1_3, quic::QUIC_VERSION_99));
+  }
+  auto proof_source = quic::CreateDefaultProofSource();
+  auto backend = backend_factory_->CreateBackend();
+  auto server =
+      server_factory_->CreateServer(backend.get(), std::move(proof_source));
+
+  if (!server->CreateUDPSocketAndListen(quic::QuicSocketAddress(
+          quic::QuicIpAddress::Any6(), GetQuicFlag(FLAGS_port)))) {
+    return 1;
+  }
+
+  server->HandleEventsForever();
+  return 0;
+}
+
+}  // namespace quic
diff --git a/quic/tools/quic_toy_server.h b/quic/tools/quic_toy_server.h
new file mode 100644
index 0000000..6c5c486
--- /dev/null
+++ b/quic/tools/quic_toy_server.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2012 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_TOOLS_QUIC_TOY_SERVER_H_
+#define QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_
+
+#include "net/third_party/quiche/src/quic/core/crypto/proof_source.h"
+#include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
+#include "net/third_party/quiche/src/quic/tools/quic_spdy_server_base.h"
+
+namespace quic {
+
+// A binary wrapper for QuicServer.  It listens forever on --port
+// (default 6121) until it's killed or ctrl-cd to death.
+class QuicToyServer {
+ public:
+  // A factory for creating QuicSpdyServerBase instances.
+  class ServerFactory {
+   public:
+    virtual ~ServerFactory() = default;
+
+    // Creates a QuicSpdyServerBase instance using |backend| for generating
+    // responses, and |proof_source| for certificates.
+    virtual std::unique_ptr<QuicSpdyServerBase> CreateServer(
+        QuicSimpleServerBackend* backend,
+        std::unique_ptr<ProofSource> proof_source) = 0;
+  };
+
+  // A facotry for creating QuicSimpleServerBackend instances.
+  class BackendFactory {
+   public:
+    virtual ~BackendFactory() = default;
+
+    // Creates a new backend.
+    virtual std::unique_ptr<QuicSimpleServerBackend> CreateBackend() = 0;
+  };
+
+  // A factory for creating QuicMemoryCacheBackend instances, configured
+  // to load files from disk, if necessary.
+  class MemoryCacheBackendFactory : public BackendFactory {
+   public:
+    std::unique_ptr<quic::QuicSimpleServerBackend> CreateBackend() override;
+  };
+
+  // Constructs a new toy server that will use |server_factory| to create the
+  // actual QuicSpdyServerBase instance.
+  QuicToyServer(BackendFactory* backend_factory, ServerFactory* server_factory);
+
+  // Connects to the QUIC server based on the various flags defined in the
+  // .cc file, listends for requests and sends the responses. Returns 1 on
+  // failure and does not return otherwise.
+  int Start();
+
+ private:
+  BackendFactory* backend_factory_;  // Unowned.
+  ServerFactory* server_factory_;    // Unowned.
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_TOOLS_QUIC_TOY_SERVER_H_