HTTP Server¶
udho provides varying types of servers depending on the logging and session facilities. A server is called stateful if it provides HTTP session, otherwise it is called stateless. If the server provides APIs that do noy require any session then use stateless server, otherwise use a stateful server. If no logging is required then use a quiet
server that uses a void logger, otherwise use a logging server. The servers udho::servers::ostreamed::stateless
and udho::servers::ostreamed::stateful<>
used in the examples are stateless and stateful servers respectively that uses ostreamed logger present inside udho. All servers inside udho::servers
namespace are typedef’ed udho::server
.
Logged Stateless Server¶
udho::servers::stateless::logged<LoggerT>
udho::servers::logged<LoggerT>::stateless
Quiet Stateless Server¶
udho::servers::stateless::quiet
udho::servers::quiet::stateless
Logged Stateful Server¶
udho::servers::stateful<States...>::logged<LoggerT>
udho::servers::logged<LoggerT>::stateful<States...>
Quiet Stateful Server¶
udho::servers::stateful<States...>::quiet
udho::servers::quiet::stateful<States...>
udho comes with a logger udho::loggers::ostream
that prints logginf messages to std::ostream
. This logger is used in all examples. So there is a typedef servers::stateful<States...>::ostreamed
that actually is servers::stateful<States...>::logged<loggers::ostream>
A Logging server takes reference to a logger in constructor. So the Logger has to be instantiated by the caller, as shown in the following example.
udho::loggers::ostream logger(std::cout);
udho::servers::stateful<StateA, StateB>::ostreamed server(logger);
For ease of access there is an ostreamed
server is provided which owns the ostream logger inside. To use this server, no logger has to be instantiated. Only the stream (std::cout) has to be provided. through the constructor.
udho::servers::ostreamed::stateless
udho::servers::ostreamed::stateful<StateA, StateB>
States¶
The stateful server uses session cookie for remembering a returning user. The session cookie is named UDHOSESSID
. For each session some information can be stored at server side. This type of features are useful for login, captcha, CSRF token etc.. udho takes advantage of stateful nation of C++ and provides session functionality around a set of states defined at compile time. A state can be any copiable C++ type. Once a stateful server is instantiated with N
number of states, callables that takes stateful contexts with M <= N
states can be used.
struct student{
std::string first_name;
std::string last_name;
unsigned int registration_id;
};
struct appearence{
std::string theme;
};
Using these two states a server can be defined as following.
udho::servers::ostreamed::stateful<student, appearence> server(std::cout);
A function taking a stateful context around zero or more of these two states can be used in the router when the above server is used. So all four (func1
, func2
, func3
, and func4
) are valid functions that can be mapped with the router when the above mentioned server is used.
std::string func1(udho::contexts::stateful<student, appearence> ctx){
// ...
}
std::string func2(udho::contexts::stateful<student> ctx){
// ...
}
std::string func3(udho::contexts::stateful<appearence> ctx){
// ...
}
std::string func4(udho::contexts::stateless ctx){
// ...
}
In these functions the corresponding values of the current session of the requested type can be accessed like the following.
std::string func1(udho::contexts::stateful<student, appearence> ctx){
bool student_data_exists = ctx.session().exists<student>();
if(!student_data_exists){
student data;
data.first_name = "Jane";
data.last_name = "Doe";
data.registration_id = 1;
ctx.session() << data;
}else{
student data;
ctx.session() >> data;
std::cout << data.first_name << std::endl;
}
}