Use the published image
Make sure you meet the following prerequisites:
docker
is 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/wsic
Build and run image
Make sure you meet the following prerequisites:
docker
is installed locally or configured to use another server
# Clone the repository (or download it)
git clone ssh://git@git.axgn.se:2222/wsic/wsic.git
# Build the wsic docker image
cd wsic && make docker
# Run on port 8080
docker run -it -p8080:8080 wsic/wsic
Make sure you meet the following prerequisites:
openssl 1.1.1
is installed (apt install libssl1.1
on Ubuntubrew install openssl@1.1
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:
$CC
refers togcc
9 (brew install gcc
on macOS) orclang
7xxd
is installed (default on many distributions)gnu sed
is installed and available assed
(default on many distributions,brew install gnu-sed
on macOS)openssl 1.1.1
is available in the system include path or/usr/local/opt/openssl@1.1/include
(apt install libssl-dev
on Ubuntu,brew install openssl@1.1
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://git@git.axgn.se:2222/wsic/wsic.git
# Build wsic
cd wsic && make
# Run
./build/wsic
The 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 = false
The 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:
$CC
refers togcc
9 (brew install gcc
on macOS) orclang
7xxd
is installed (default on many distributions)gnu sed
is installed and available assed
(default on many distributions,brew install gnu-sed
on macOS)clang
7 is installedgcov
refers to version 9 which comes withgcc
lcov
is installed (brew install lcov
on macOS)fastcov
is installed (pip3 install fastcov
)scan-build
refers to version 7 which comes withclang
clang-format
refers to version 7 which comes withclang
openssl 1.1.1
is available in the system include path or/usr/local/opt/openssl@1.1/include
(apt install libssl-dev
on Ubuntu,brew install openssl@1.1
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://git@git.axgn.se: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/test
The 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.