Use the published image
Make sure you meet the following prerequisites:
dockeris installed locally or configured to use another server- You're authorized to pull from registry.axgn.se
docker login registry.axgn.se
docker run -it -p8080:8080 registry.axgn.se/wsic/wsicBuild and run image
Make sure you meet the following prerequisites:
dockeris installed locally or configured to use another server
# Clone the repository (or download it)
git clone ssh://[email protected]:2222/wsic/wsic.git
# Build the wsic docker image
cd wsic && make docker
# Run on port 8080
docker run -it -p8080:8080 wsic/wsicMake sure you meet the following prerequisites:
openssl 1.1.1is installed (apt install libssl1.1on Ubuntubrew install [email protected]on macOS)
You can download the latest development build here and the latest release here. Currently, these builds only run on Ubuntu with the amd64 architecture.
Make sure you meet the following prerequisites:
$CCrefers togcc9 (brew install gccon macOS) orclang7xxdis installed (default on many distributions)gnu sedis installed and available assed(default on many distributions,brew install gnu-sedon macOS)openssl 1.1.1is available in the system include path or/usr/local/opt/[email protected]/include(apt install libssl-devon Ubuntu,brew install [email protected]on macOS)
NOTE: For instructions on how to install all the prerequisites and building on Ubuntu, refer to the Dockerfile.
# Clone the repository (or download it)
git clone ssh://[email protected]:2222/wsic/wsic.git
# Build wsic
cd wsic && make
# Run
./build/wsicThe documentation is currently a bit sparse. For more information, refer to the source, tests and issues.
WSIC uses a modern approach to concurrency. Everything is entirely event-driven which allows for 0 idle CPU usage and close to 0 MB of memory usage.
WSIC also features a main process with the sole purpose of monitoring a server process. It sleeps most of the time and checks in from time to time or whenever the child process exits. In the vast majority cases WSIC is therefore able to recover from unexpected crashes with very low downtime measuring in milliseconds.
The server process of WSIC offers multiplexing with support for an amount of listening virtual hosts only limited by the host system. As quick as possible, WSIC accepts incoming requests and put them in a multi-threaded message queue.
This queue is consumed by a pool of worker which handles each request separately and concurrently. Whenever a worker is done handling a connection, it gets back to consuming the message queue which enables the worker to sleep most of the time. As previously stated, this allows WSIC to consume near 0 resources when idle.
Processes started by WSIC inherits its permissions. This only really affects CGI processes. This means that if WSIC has access to a file, so do CGI processes. It's therefore important to configure WSIC to run as a seperate user on the system with access only to necessery parts. If possible, one can deploy jails or containers (see Running with docker).
Configuring WSIC is generally done by a config file written in TOML. An example configuration looks like this:
[server]
daemon = false
[servers]
[servers.default]
domain = "localhost"
rootDirectory = "www"
port = 8080
directoryIndex = ["index.html", "index.sh"]
[servers.defaultTLS]
domain = "localhost"
rootDirectory = "www"
port = 8443
directoryIndex = ["index.html", "index.sh"]
certificate = "server.cert"
privateKey = "server.key"
ellipticCurves = "P-384:P-521"
validateCertificate = falseThe server block has the following options.
| Name | Description | Example |
|---|---|---|
| daemon | Bool. Whether or not the process should be run in daemon mode. Defaults to false. |
daemon = true |
| logfile | String. An optional path to a logfile to write logs to. Default is empty. | logfile = "logs.txt" |
| loggingLevel | Integer (0-7). The syslog log level to use. Defaults to notice (5). | loglevel = 5 |
| threads | Integer larger or equal to 1. The number of worker threads to use. Default is 32. | threads = 16 |
| backlog | Integer (0-SOMAXCONN). The number of sockets allowed in the backlog (in the kernel, WSIC's queue has no limit). Defaults to SOMAXCONN (roughly 128). |
backlog = 64 |
The servers block takes one or more servers with the following options.
| Name | Description | Example |
|---|---|---|
| domain | Required string. The domain to handle. May be used once for HTTP and once for HTTPS. | domain = wsic.axgn.se |
| port | Required integer (0-65536). The port to listen on. May be used multiple times. | port = 80 |
| rootDirectory | Required string. The root directory (www directory) of the website. | rootDirectory = "/var/www" |
| directoryIndex | Array of strings. The index files to check when a directory is requested. No default (directory index will cause HTTP 404 Not Found) |
rootDirectory = ["index.html", "index.sh"] |
| dhparams | String. Path to a file in PEM format specifying Diffie Hellman parameters to use for RSA ephemeral keys. No default. | dhparams = dhparams.pem |
| privateKey | String. Required for TLS. Path to a private key file in PEM format specifying the private key of the server. | privateKey = "server.pem" |
| certificate | String. Required for TLS. Path to a certificate file in PEM format specifying the server certificate to use. | certificate = "server.cert" |
| ellipticCurves | String. Elliptic curves to use. Default is specified in config.h. | ellipticCuvers = "P-256:P-384:X25519" |
| cipherSuite | String. The cipher suite to use for TLS 1.2 (TLS 1.3 is hard-coded). Supported values are those for TLS 1.2 and TLS 1.3 specified here: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html. Default is specified in config.h. | cipherSuite = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256" |
| enabled | Bool. Currently unused | enabled = false |
Any contribution is welcome. If you're not able to code it yourself, perhaps someone else is - so post an issue if there's anything on your mind.
Make sure you meet the following prerequisites:
$CCrefers togcc9 (brew install gccon macOS) orclang7xxdis installed (default on many distributions)gnu sedis installed and available assed(default on many distributions,brew install gnu-sedon macOS)clang7 is installedgcovrefers to version 9 which comes withgcclcovis installed (brew install lcovon macOS)fastcovis installed (pip3 install fastcov)scan-buildrefers to version 7 which comes withclangclang-formatrefers to version 7 which comes withclangopenssl 1.1.1is available in the system include path or/usr/local/opt/[email protected]/include(apt install libssl-devon Ubuntu,brew install [email protected]on macOS)
NOTE: For instructions on how to install all the prerequisites on Ubuntu, refer to the CI image used by WSIC over at https://gitlab.axgn.se/wsic/ci-image (see Dockerfile).
# Clone the repository
git clone ssh://[email protected]:2222/wsic/wsic.git && cd wsic
# Lint
make lint
# Perform static analysis
make analyze
# The report is now available in build/reports/static-analysis
# Format the code
make format
# Build and run a debugging build (memory analyzer and GDB debugging enabled)
make debug && ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=suppressions=asan-ignores.txt ./build/wsic.debug
# Build and run a release build
make build && ./build
# Build a test build and run unit tests
make test && ./ci/test.sh
# Coverage report is now available in build/reports/testThe branches master and development are locked for pushing. Code is merged in to development by feature branches named feature/my-feature, fix/my-fix or the like. Try to keep the names concise and descriptive.
The feature branches should when applicable be up to speed to development via git rebase development. Feature branches are merged to development with git merge --no-ff branch. Feature branches may be squashed, but prefer to keep the history clean so that all commits can be kept.
When development is stable enough and provides meaningful value, it is merged into the master branch. First, a release-vx.x.x branch is created in development with updates reflecting the version change. When that branch is merged to development, an annotated tag is created in development using git tag -a vx.x.x -m "Version x.x.x". Then development is merged into master.
Although the project is very capable, it is not built with production in mind. Therefore there might be complications when trying to use the server for large-scale projects meant for the public. The server was written by students as part of a course at BTH, Sweden and as such it might not promote best practices nor be performant.

