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_