C++ Web Server Adapter
This repository defines a library-agnostic API for C++ to work with a web server.
Supported features
- Server and client
- HTTP
- HTTPS
- Mutual SSL
- CORS
- Thread pool
- GZIP compression
Available implementations
Usage
Use of this library begins with an instance of:
systelab::web_server::IServerFactory
class (for server features)systelab::web_server::IClientFactory
class (for client features)
See documentation of selected implementation for details about how to build one.
HTTP server set up
Set up a new HTTP web server by providing a configuration object that specifies host address and port:
systelab::web_server::Configuration configuration;
configuration.setHostAddress("127.0.0.1");
configuration.setPort(8080);
systelab::web_server::IServerFactory& serverFactory = ...
std::unique_ptr<systelab::web_server::IServer> server = serverFactory.buildServer(configuration);
Then, register at least a web service by providing an instance of a class that implements the systelab::web_server::IWebService
interface:
class MyWebService : public systelab::web_server::IWebService
{
std::unique_ptr<systelab::web_server::Reply> execute(const systelab::web_server::Request& request)
{
std::unique_ptr<systelab::web_server::Reply> reply;
if (canServiceHandleRequest(request))
{
// Process request and build a reply
}
return reply;
}
}
auto webService = std::make_unique<MyWebService>();
webServer->registerWebService(std::move(webService));
Finally, start the server calling the start()
method:
webServer->start();
HTTPS
HTTPS can be enabled through the configuration object provided when creating the server. The systelab::web_server::SecurityConfiguration
class allows defining the paths of the certificate files as follows:
systelab::web_server::Configuration configuration;
systelab::web_server::SecurityConfiguration& securityConfiguration = configuration.getSecurityConfiguration();
securityConfiguration.setHTTPSEnabled(true);
securityConfiguration.setServerCertificate("Server.cert");
securityConfiguration.setServerPrivateKey("Server.key");
securityConfiguration.setServerDHParam("Server.dhparam");
Additionally, support for specific TLS versions can be enabled/disabled:
securityConfiguration.setTLSv12Enabled(false);
securityConfiguration.setTLSv13Enabled(true);
By default only TLS v1.2 is enabled. TLS v1.3 needs to be enabled on demand because it is not supported before OpenSSL 1.1.1. Older TLS versions should be always disabled as they have known security vulnerabilities.
Mutual SSL
To enable use of mutual SSL, the path of the client certificate must be specified through the security configuration of the server:
systelab::web_server::SecurityConfiguration& securityConfiguration = configuration.getSecurityConfiguration();
securityConfiguration.setMutualSSLEnabled(true);
securityConfiguration.setClientCertificate("Client.cert");
CORS configuration
The CORS configuration of the server can be defined using the systelab::web_server::CORSConfiguration
class:
systelab::web_server::Configuration configuration;
systelab::web_server::CORSConfiguration& corsConfiguration = configuration.getCORSConfiguration();
corsConfiguration.setEnabled(true);
corsConfiguration.setAllowedOrigins({"http://127.0.0.1:4200", "http://127.0.0.1:8082"});
corsConfiguration.setAllowedMethods({"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"});
corsConfiguration.setAllowedHeaders({"Origin", "Authorization", "Content-Type"});
corsConfiguration.setExposedHeaders({"Origin", "Authorization", "Content-Type"});
corsConfiguration.setMaxAge(1209600);
corsConfiguration.setAllowedCredentials(true);
Thread pool configuration
The size of the pool of threads dedicated to attend server requests can be specified using the configuration option:
systelab::web_server::Configuration configuration;
configuration.setThreadPoolSize(4);
GZIP compression
The server can be configured to automatically apply gzip compression to payload of replies by enabling the following configuration option:
systelab::web_server::Configuration configuration;
configuration.setGZIPCompressionEnabled(true);
HTTP/HTTPS client usage
Set up a new HTTP client by providing a server IP address and a port number:
systelab::web_server::IClientFactory& clientFactory = ...
std::unique_ptr<systelab::web_server::IClient> client = clientFactory.buildHTTPClient("127.0.0.1", 8080);
Similarly, an HTTPS client can be created as follows:
systelab::web_server::IClientFactory& clientFactory = ...
std::unique_ptr<systelab::web_server::IClient> client = clientFactory.buildHTTPSClient("localhost", 9090);
Then, the returned systelab::web_server::IClient
object can be used to send requests to the server:
systelab::web_server::Request request;
request.setMethod("POST");
request.setURI("/rest/api/login");
request.setContent("PasswordGoesHere");
request.getHeaders().addHeader("Content-Type", "text/plain");
std::unique_ptr<Reply> reply = client->send(request);
systelab::web_server::Reply::StatusType status = reply->getStatus();
std::map<std::string, std::string> headers = reply->getHeaders();
std::string content = reply->getContent();