| // Copyright 2018 The Fuchsia 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 SRC_CHROMIUM_WEB_RUNNER_TESTS_TEST_SERVER_H_ | |
| #define SRC_CHROMIUM_WEB_RUNNER_TESTS_TEST_SERVER_H_ | |
| #include <lib/fit/defer.h> | |
| #include <array> | |
| #include <string> | |
| #include <thread> | |
| #include <vector> | |
| #include <fbl/unique_fd.h> | |
| namespace web_runner_tests { | |
| // This is a simple TCP server that binds to a random port on localhost and | |
| // serves a single connection. | |
| class TestServer { | |
| public: | |
| // This attempts to find an available port the server to. | |
| bool FindAndBindPort(); | |
| // Closes the bound socket file descriptor, cancelling any pending |Accept|. | |
| void Close(); | |
| // This accepts exactly one incoming connection. | |
| bool Accept(); | |
| // This reads data from the currently open connection into the provided | |
| // |buf|. On success, this resizes |buf| to the number of bytes read. | |
| bool Read(std::string* buf); | |
| // Writes data from |buf| into the currently open connection. | |
| bool Write(const std::string& buf); | |
| // Writes message content into the currently open connection, preceeded by an | |
| // appropriate HTTP response header. | |
| bool WriteContent(const std::string& content); | |
| // Port number in use. | |
| int port() const { return port_; } | |
| // Runs a |serve| routine on its own thread, with proper cleanup to prevent | |
| // deadlock. |serve| must terminate after |Accept()| returns false. | |
| // The return value is a deferred action which, when destroyed, closes | |
| // the server (i.e. RAII semantics). | |
| template <typename T> | |
| auto ServeAsync(T serve) { | |
| auto server = std::thread(std::move(serve)); | |
| // Close must be signaled before the thread goes out of scope so that any | |
| // blocking |Accept| calls terminate so that |serve| can terminate. | |
| return fit::defer([this, server = std::move(server)]() mutable { | |
| Close(); | |
| server.join(); | |
| }); | |
| } | |
| private: | |
| fbl::unique_fd conn_; | |
| fbl::unique_fd socket_; | |
| std::array<fbl::unique_fd, 2> close_; | |
| int port_ = -1; | |
| }; | |
| } // namespace web_runner_tests | |
| #endif // SRC_CHROMIUM_WEB_RUNNER_TESTS_TEST_SERVER_H_ |