Skip to content

Commit

Permalink
thevoid: Added documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruslan Nigmatullin committed Apr 1, 2014
1 parent 2e05131 commit f8b6b00
Show file tree
Hide file tree
Showing 4 changed files with 427 additions and 24 deletions.
4 changes: 2 additions & 2 deletions doc/CMakeLists.txt
Expand Up @@ -6,8 +6,8 @@ SET( SWARM_DOC_BRIEF_MEMBER_DESC NO CACHE STRING "Include brief member descripti
SET( SWARM_DOC_EXTRACT_PRIVATE NO CACHE STRING "" )
SET( SWARM_DOC_EXTRACT_STATIC NO CACHE STRING "" )
SET( SWARM_DOC_QUIET NO CACHE STRING "Quiet documentation generation" )
SET( SWARM_DOC_FILE_PATTERNS "*.h *.c *.hpp *.cpp" CACHE STRING "Space separated wildcard patterns" )
SET( SWARM_DOC_EXCLUDE_PATTERNS *_p.h CACHE STRING "Space separated wildcard patterns" )
SET( SWARM_DOC_FILE_PATTERNS "*.h *.hpp" CACHE STRING "Space separated wildcard patterns" )
SET( SWARM_DOC_EXCLUDE_PATTERNS "*_p.h *_p.hpp" CACHE STRING "Space separated wildcard patterns" )
SET( SWARM_DOC_EXCLUDE_SYMBOLS d_ptr CACHE STRING "Space separated wildcard patterns" )
SET( SWARM_DOC_SOURCE_BROWSER NO CACHE STRING "" )
SET( SWARM_DOC_INLINE_SOURCES NO CACHE STRING "" )
Expand Down
2 changes: 2 additions & 0 deletions swarm/urlfetcher/stream.hpp
Expand Up @@ -24,6 +24,8 @@ namespace swarm {

/*!
* \brief The simple_stream class makes possible to handle only final result for the requests.
*
* \sa base_stream
*/
class simple_stream : public base_stream
{
Expand Down
201 changes: 179 additions & 22 deletions thevoid/server.hpp
Expand Up @@ -46,31 +46,14 @@ class url;
}
namespace thevoid {

namespace detail {

template<typename Parent, typename Type>
struct check {
private:
typedef char true_type;
class false_type { char arr[2]; };

static Type create();

static true_type process(Parent);
static false_type process(...);
public:
enum {
result = (sizeof(process(create())) == sizeof(true_type))
};
};

}

class server_data;
template <typename T> class connection;
class monitor_connection;
class server_options_private;

/*!
* \brief The daemon_exception is thrown in case if daemonization fails.
*/
class daemon_exception : public std::runtime_error
{
public:
Expand All @@ -81,67 +64,189 @@ class daemon_exception : public std::runtime_error
template <typename Server, typename... Args>
std::shared_ptr<Server> create_server(Args &&...args);

/*!
* \brief The base_server class is a base class for implementing own HTTP servers.
*
* Ususally you don't need to subclass it directly, use server for this.
*/
class base_server : private boost::noncopyable
{
public:
/*!
* \brief Constructs base server.
*/
base_server();
/*!
* \brief Destroyes the object.
*/
virtual ~base_server();

/*!
* \brief Listen for new connections at \a host.
*
* There are two possible formats for \a host:
* \li host:port or address:port - listen at certain interface at \a port.
* \li unix:path - listen unix socket at \a path.
*
* \code{.cpp}
* server.listen("127.0.0.1:80");
* server.listen("unix:/var/run/server.sock");
* \endcode
*/
void listen(const std::string &host);

/*!
* \brief Run server using provided command line arguments.
*
* Supported arguments are:
* \li help - show help message and return.
* \li config path - read configuration file \a path.
* \li pidfile file - write PID file to \a file.
*/
int run(int argc, char **argv);

/*!
* \brief Ser \a logger as logger of the server.
*/
void set_logger(const swarm::logger &logger);
/*!
* \brief Returns logger of the service.
*/
swarm::logger logger() const;

/*!
* \brief Returns server-specific statistics as a key-value map.
*
* Reimplement this if you want your own statistics available.
*/
virtual std::map<std::string, std::string> get_statistics() const;

/*!
* \brief Returns number of worker threads count.
*/
unsigned int threads_count() const;

/*!
* \brief Initialize server by application-specific section \a config from configuration file.
*
* Returns true if initialization was succesfull.
*/
virtual bool initialize(const rapidjson::Value &config) = 0;
/*!
* \brief Initialize logger by \a config.
*
* Override this method if you want to initialize your own logger.
*
* Returns true if initialization was succesfull.
*/
virtual bool initialize_logger(const rapidjson::Value &config);

protected:
/*!
* \brief The options class provides API for settings handler options.
*
* It makes possible to specify conditions at which handler should be called.
*/
class options
{
public:
typedef std::function<void (options *)> modificator;

/*!
* \brief Calls options::set_exact_match
*
* \sa set_exact_match
*/
static modificator exact_match(const std::string &str);
/*!
* \brief Calls options::set_prefix_match
*
* \sa set_prefix_match
*/
static modificator prefix_match(const std::string &str);
/*!
* \brief Calls options::set_methods
*
* \sa set_methods
*/
static modificator methods(const std::vector<std::string> &methods);
/*!
* \brief Calls options::set_methods
*
* Creates std::vector from \a args and passes it to set_methods.
*
* \sa set_methods
*/
template <typename... String>
static modificator methods(String &&...args)
{
const std::vector<std::string> tmp = { std::forward<std::string>(args)... };
return methods(tmp);
}
/*!
* \brief Calls options::set_header
*
* \sa set_header
*/
static modificator header(const std::string &name, const std::string &value);

/*!
* \brief Constructs options object.
*/
options();

options(options &&other) SWARM_NOEXCEPT;
options(const options &other) = delete;
options &operator =(options &&other);
options &operator =(const options &other) = delete;

/*!
* Destroyes the object.
*/
~options();

/*!
* \brief Makes handler callable only if path of the request is exactly equal to \a str.
*/
void set_exact_match(const std::string &str);
/*!
* \brief Makes handler callable only if path of the request starts with \a str.
*/
void set_prefix_match(const std::string &str);
/*!
* \brief Makes handler callable if HTTP method is one of \a methods.
*/
void set_methods(const std::vector<std::string> &methods);
/*!
* \brief Makes handler callable if HTTP header \a name is equal to \a value.
*/
void set_header(const std::string &name, const std::string &value);

/*!
* \brief Returns true if request satisfies all conditions.
*/
bool check(const swarm::http_request &request) const;

/*!
* \brief Swaps this options with \a other.
*/
void swap(options &other);

private:
std::unique_ptr<server_options_private> m_data;
};

/*!
* \brief Registers handler producable by \a factory with options \a opts.
*/
void on(options &&opts, const std::shared_ptr<base_stream_factory> &factory);

// This is a subject of change, don't use it
/*!
* \internal
*
* \brief Daemonize the server.
*
* Exception is thrown on error.
*/
void daemonize();

private:
Expand All @@ -151,20 +256,52 @@ class base_server : private boost::noncopyable
friend class monitor_connection;
friend class server_data;

/*!
* \internal
*/
void set_server(const std::weak_ptr<base_server> &server);
/*!
* \internal
*/
std::shared_ptr<base_stream_factory> factory(const swarm::http_request &request);

std::unique_ptr<server_data> m_data;
};

/*!
* \brief The server provides API for constructing own HTTP server.
*
* This is a base class you really should derive from.
*/
template <typename Server>
class server : public base_server, public std::enable_shared_from_this<Server>
{
public:
/*!
* \brief Creates server.
*/
server() {}
/*!
* \brief Destroyes server.
*/
~server() {}

protected:
/*!
* \brief Add new handler of type \a T with options \a args.
*
* The following example show how to handle \a on_ping on URL "/ping" for GET requests:
* \code{.cpp}
* on<on_ping>(
* options::exact_match("/ping"),
* options::methods("GET")
* );
* \endcode
*
* Handler must be a successor of base_request_stream.
*
* \sa options
*/
template <typename T, typename... Options>
void on(Options &&...args)
{
Expand All @@ -174,19 +311,30 @@ class server : public base_server, public std::enable_shared_from_this<Server>
}

private:
/*!
* \internal
*/
template <typename Option>
Option &&apply_option(options &opt, Option &&option)
{
option(&opt);
return std::forward<Option>(option);
}

/*!
* \internal
*/
template <typename... Options>
void options_pass(Options &&...)
{
}
};

/*!
* \brief Creates server with \a args, they are passed to \a Server's constructor.
*
* Server is created via std::make_shared, so std::enable_shared_from_this works.
*/
template <typename Server, typename... Args>
std::shared_ptr<Server> create_server(Args &&...args)
{
Expand All @@ -195,6 +343,15 @@ std::shared_ptr<Server> create_server(Args &&...args)
return server;
}

/*!
* \brief Run server \a Server with \a args.
*
* It's equivalent to:
* \code{.cpp}
* auto server = create_server<Server>(args);
* return server->run(argc, argv);
* \encode
*/
template <typename Server, typename... Args>
int run_server(int argc, char **argv, Args &&...args)
{
Expand Down

0 comments on commit f8b6b00

Please sign in to comment.