1 unstable release
0.1.0 | Jul 6, 2023 |
---|
#3 in #modularity
14KB
145 lines
Servar - Multi Utility Server
Goals
Servar is eventually designed to be able to replace:
- netcat
- socat
- python's HTTP serve
And pretty much any other utility you can or want to hook up to the network. Our design goal is modularity and cross compatibility; this tool should work as well on any platform that can compile Rust.
While combining as many tools as possible, we are aiming to keep the flags at least very similar.
We are also not trying to steal the spotlight of any particular tool. Although we are trying to cram a lot of the "core" functionalities of various tools, we are not trying to replicate all the specialized features (at least for now). Inch deep, mile wide.
Usage
Servar is designed to be very simple to use, with most of the flexibility coming from the sub-modules. By using Rust's structopt
library we are able to provide detailed yet flexible help menus.
USAGE:
servar [OPTIONS] <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-i, --ip <ip> Listen IP [default: 0.0.0.0]
-p, --port <port> Listen Port [default: 8000]
SUBCOMMANDS:
help Prints this message or the help of the given subcommand(s)
http-dir Serves a directory via HTTP
To serve the /tmp directory over HTTP on port 8080:
servar -p 8080 htt-dir /tmp
Adding a Module
Adding a module is very simple. The source tree should look like:
main.rs
module_name/
-> mod.rs
-> module_name.rs
mod.rs
shall export the two required things to integrate it. the Args
struct and the entrypoint exec
function.
To integrate it into the core tool, only 2 lines of code are required. The first adds an entry to the Modes enum, and the second adds a match for the entry point.
pub enum ServerMode {
HTTPDir(httpdir::Args),
}
------------------------
match args.mode {
ServerMode::HTTPDir(mod_args) => httpdir::exec(gargs, mod_args).await?,
}
And that's all there is! As more global arguments are added, these will be exposed to the module, and all the module specific argument handling is done by the module itself.
For an example of this, please see the httpdir
module.
Results
Currently, only the HTTP side is supported. Here is a simple benchmark using wrk
that compares the python module (top results) to the servar (bottom):
❯ ./wrk -t12 -c400 -d30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 10.02ms 61.32ms 1.82s 97.98%
Req/Sec 300.42 239.27 1.60k 67.01%
86753 requests in 30.09s, 55.10MB read
Socket errors: connect 0, read 0, write 0, timeout 44
Requests/sec: 2883.49
Transfer/sec: 1.83MB
❯ ./wrk -t12 -c400 -d30s http://localhost:8000/
Running 30s test @ http://localhost:8000/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.50ms 4.34ms 211.01ms 73.87%
Req/Sec 5.30k 677.75 13.70k 96.56%
1899670 requests in 30.10s, 1.04GB read
Requests/sec: 63111.88
Transfer/sec: 35.51MB
As you can see, over the same 30s period, servar was able to handle more than double the ammount of connections, at almost 2x the speed.
Dependencies
~11–21MB
~285K SLoC