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_