1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
// Copyright Maarten L. Hekkelman, Radboud University 2008-2013.
// Copyright Maarten L. Hekkelman, 2014-2022
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
/// \file
/// Code for a preforked http server implementation
#include <zeep/config.hpp>
#include <zeep/http/server.hpp>
#if HTTP_SERVER_HAS_PREFORK
namespace zeep::http
{
/// \brief class to create a preforked HTTP server
///
/// A preforked server means you have a master process that listens to a port
/// and whenever a request comes in, the socket is passed to a client. This
/// client will then process the request.
/// This approach has several advantages related to security and stability.
///
/// The way it works in libzeep is, you still create a server that derives
/// from zeep::server (if you need a SOAP server) or zeep::http::server (if
/// you only want a HTTP server). You then create a
/// zeep::http::preforked_server<YourServer> instance passing in the
/// parameters required and then call run() on this preforked server.
///
/// The preforked_server class records the way your server needs to be
/// constructed. When this preforked_server is run, it forks and then
/// constructs your server class in the child process.
///
/// Example:
/// \code{.cpp}
/// class my_server {
/// public:
/// my_server(const string& my_param);
///
/// ....
///
/// zeep::http::preforked_server<my_server> server(
/// []() { return new my_server("my param value"); }
/// );
///
/// // all addresses, port 10333 and two listener threads
/// std::thread t(std::bind(&zeep::http::preforked_server::run, &server, "0.0.0.0", 10333, 2));
///
/// ... // wait for signal to stop
///
/// server.stop();
/// t.join();
/// \endcode
class child_process;
class preforked_server
{
public:
preforked_server(const preforked_server&) = delete;
preforked_server& operator=(const preforked_server&) = delete;
/// \brief constructor
///
/// The constructor takes one argument, a function object that creates
/// a server class instance.
preforked_server(std::function<basic_server*(void)> server_factory);
virtual ~preforked_server();
/// \brief forks \a nr_of_child_processes children and starts listening, should be a separate thread
virtual void run(const std::string& address, short port, int nr_of_child_processes, int nr_of_threads);
virtual void start(); ///< signal the thread it can start listening:
virtual void stop(); ///< stop the running thread
private:
std::function<basic_server*(void)> m_constructor;
std::mutex m_lock;
boost::asio::io_context m_io_context;
};
}
#endif
|