Skip to content

Commit

Permalink
Initial user manual (#55)
Browse files Browse the repository at this point in the history
* Initial user manual commit

* Write a lot of docs

* Finish docs
  • Loading branch information
jamesmunns authored Jul 24, 2024
1 parent f62021a commit 4ad8b40
Show file tree
Hide file tree
Showing 14 changed files with 564 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: taiki-e/install-action@v2
with:
tool: mdbook
fallback: none
- run: ./ci.sh
5 changes: 5 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ cd ./source/river
cargo run -p river -- --config-toml ./assets/example-config.toml --validate-configs
cargo run -p river -- --config-toml ./assets/test-config.toml --validate-configs
cargo run -p river -- --config-kdl ./assets/test-config.kdl --validate-configs
cd ../../

# ensure the user manual can be built
cd user-manual
mdbook build
1 change: 1 addition & 0 deletions user-manual/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
book
6 changes: 6 additions & 0 deletions user-manual/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[book]
authors = ["James Munns"]
language = "en"
multilingual = false
src = "src"
title = "River User Manual"
11 changes: 11 additions & 0 deletions user-manual/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Summary

- [Introduction](./intro.md)
- [Installation](./install.md)
- [Core Concepts](./concepts/mod.md)
- [Configuration](./config/mod.md)
- [Command Line Interface](./config/cli.md)
- [Environment Variables](./config/env.md)
- [Configuration File (KDL)](./config/kdl.md)
- [Configuration File (TOML)](./config/toml.md)
- [Hot Reloading](./reloading.md)
106 changes: 106 additions & 0 deletions user-manual/src/concepts/mod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Core Concepts

River is a Reverse Proxy application.

It is intended to handle connections from **Downstream** clients, forward
**Requests** to **Upstream** servers, and then forward **Responses** from
the **Upstream** servers back to the **Downstream** clients.

```text
┌────────────┐ ┌─────────────┐ ┌────────────┐
│ Downstream │ ┌ ─│─ Proxy ┌ ┼ ─ │ Upstream │
│ Client │─────────▶│ │ │──┼─────▶│ Server │
└────────────┘ │ └───────────┼─┘ └────────────┘
─ ─ ┘ ─ ─ ┘
▲ ▲
┌──┘ └──┐
│ │
┌ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─
Listeners Connectors│
└ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─
```

For the purpose of this guide, we define **Requests** as messages sent
from the downstream client to the upstream server, and define **Responses**
as messages sent from the upstream server to the downstream client.

River is capable of handling connections, requests, and responses from
numerous downstream clients and upstream servers simultaneously.

When proxying between a downstream client and upstream server, River
may modify or block requests or responses. Examples of modification
include the removal or addition of HTTP headers of requests or responses,
to add internal metadata, or to remove sensitive information. Examples
of blocking include the rejection of requests for authentication or
rate limiting purposes.

## Services

River is oriented around the concept of **Services**. **Services** are
composed of three major elements:

* **Listeners** - the sockets used to accept incoming connections from
downstream clients
* **Connectors** - the listing of potential upstream servers that requests
may be forwarded to
* **Path Control Options** - the modification or filtering settings used
when processing requests or responses.

Services are configured independently from each other. This allows a single
instance of the River application to handle the proxying of multiple different
kinds of traffic, and to apply different rules when proxying these different
kinds of traffic.

Each service also creates its own pool of worker threads, in order to allow for
the operating system to provide equal time and resources to each Service,
preventing one highly loaded Service from starving other Services of resources
such as memory and CPU time.

## Listeners

Listeners are responsible for accepting incoming connections and requests
from downstream clients. Each listener is a single listening socket, for
example listening to IPv4 traffic on address `192.168.10.2:443`.

Listeners may optionally support the establishment and termination of TLS.
They may be configured with a TLS certificate and [SNI], allowing them
to securely accept traffic sent to a certain domain name, such as
`https://example.com`.

[SNI]: https://www.cloudflare.com/en-gb/learning/ssl/what-is-sni/

Unlike some other reverse proxy applications, in River, a given listener
is "owned" by a single service. This means that multiple services may not
be listening to the same address and port. Traffic received by a given
Listener will always be processed by the same Service for the duration
of time that the River application is running.

Listeners are configured "statically": they are set in the configuration
file loaded at the start of the River application, and are constant for
the time that the River application is running.

## Connectors

Connectors are responsible for the communication between the Service and
the upstream server(s).

Connectors manage a few important tasks:

* Allowing for Service Discovery, changing the set up potential upstream servers over time
* Allowing for Health Checks, selectively enabling and disabling which upstream servers
are eligible for proxying
* Load balancing of proxied requests across multiple upstream servers
* Optionally establishing secure TLS connections to upstream servers
* Maintaining reusable connections to upstream servers, to reduce the cost of connection
and proxying

Similar to Listeners, each Service maintains its own unique set of Connectors. However,
Services may have overlapping sets of upstream servers, each of them considering an
upstream server in the list of proxy-able servers in their own connectors. This allows
multiple services to proxy to the same upstream servers, but pooled connections and
other aspects managed by Connectors are not shared across Services.

## Path Control

Path Control allows for configurable filtering and modification of requests and
responses at multiple stages of the proxying process.
79 changes: 79 additions & 0 deletions user-manual/src/config/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Command Line Interface

```text
River: A reverse proxy from Prossimo
Usage: river [OPTIONS]
Options:
--validate-configs
Validate all configuration data and exit
--config-toml <CONFIG_TOML>
Path to the configuration file in TOML format
--config-kdl <CONFIG_KDL>
Path to the configuration file in KDL format
--threads-per-service <THREADS_PER_SERVICE>
Number of threads used in the worker pool for EACH service
--daemonize
Should the server be daemonized after starting?
--upgrade
Should the server take over an existing server?
--upgrade-socket <UPGRADE_SOCKET>
Path to upgrade socket
--pidfile <PIDFILE>
Path to the pidfile, used for upgrade
-h, --help
Print help
```

## `--validate-configs`

Running River with this option will validate the configuration, and immediately exit
without starting any Services. A non-zero return code will be given when the configuration
fails validation.

## `--config-toml <CONFIG_TOML>`

Running River with this option will instruct River to load the configuration file from
the provided path. Cannot be used with `--config-kdl`.

## `--config-kdl <CONFIG_KDL>`

Running River with this option will instruct River to load the configuration file from
the provided path. Cannot be used with `--config-toml`.

## `--threads-per-service <THREADS_PER_SERVICE>`

Running River with this option will instruct River to use the given number of worker
threads per service.

## `--daemonize`

Running River with this option will cause River to fork after the creation of all
Services. The application will return once all Services have been started.

If this option is not provided, the River application will run until it is commanded
to stop or a fatal error occurs.

## `--upgrade`

Running River with this option will cause River to take over an existing River
server's open connections. See [Hot Reloading] for more information about this.

[Hot Reloading]: ../reloading.md

## `--upgrade-socket <UPGRADE_SOCKET>`

Running River with this option will instruct River to look at the provided socket
path for receiving active Listeners from the currently running instance.

This must be an absolute path. This option only works on Linux.

See [Hot Reloading] for more information about this.

## `--pidfile <PIDFILE>`

Running River with this option will set the path for the created pidfile when
the server is configured to daemonize.

This must be an absolute path.
3 changes: 3 additions & 0 deletions user-manual/src/config/env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Environment Variables

TODO: We don't use any environment variables yet
Loading

0 comments on commit 4ad8b40

Please sign in to comment.