blob: 18571c7f1041645016d93613c929a0df97b01231 [file] [log] [blame]
// 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.
#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 {
// 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 {
fbl::unique_fd conn_;
fbl::unique_fd socket_;
std::array<fbl::unique_fd, 2> close_;
int port_ = -1;
} // namespace web_runner_tests