harden runtime config and docs
This commit is contained in:
@@ -311,9 +311,13 @@ The example contains the filesystem and FastCGI settings:
|
|||||||
BIN_DIRECTORY=/var/cache/uce/work
|
BIN_DIRECTORY=/var/cache/uce/work
|
||||||
TMP_UPLOAD_PATH=/var/lib/uce/uploads
|
TMP_UPLOAD_PATH=/var/lib/uce/uploads
|
||||||
SESSION_PATH=/var/lib/uce/sessions
|
SESSION_PATH=/var/lib/uce/sessions
|
||||||
|
SESSION_COOKIE_SECURE=1
|
||||||
|
|
||||||
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
||||||
|
FCGI_SOCKET_MODE=0666
|
||||||
FCGI_PORT=9993
|
FCGI_PORT=9993
|
||||||
|
CLI_SOCKET_PATH=/run/uce/cli.sock
|
||||||
|
CLI_SOCKET_MODE=0600
|
||||||
|
|
||||||
PRECOMPILE_FILES_IN=
|
PRECOMPILE_FILES_IN=
|
||||||
SITE_DIRECTORY=/var/www/html
|
SITE_DIRECTORY=/var/www/html
|
||||||
@@ -328,7 +332,7 @@ For nginx deployments, the most important setting is:
|
|||||||
|
|
||||||
- `FCGI_SOCKET_PATH=/run/uce/fastcgi.sock`
|
- `FCGI_SOCKET_PATH=/run/uce/fastcgi.sock`
|
||||||
|
|
||||||
That is the Unix socket nginx should use for normal `.uce` requests.
|
That is the Unix socket nginx should use for normal `.uce` requests. `CLI_SOCKET_PATH` is for local admin/test execution through `scripts/uce-cli`; keep `CLI_SOCKET_MODE=0600` unless a trusted Unix group explicitly needs access.
|
||||||
|
|
||||||
`FCGI_PORT` is optional if nginx is talking to the Unix socket. Leave it set if you also want a TCP FastCGI listener, or remove it if you want the socket to be the only FastCGI entry point.
|
`FCGI_PORT` is optional if nginx is talking to the Unix socket. Leave it set if you also want a TCP FastCGI listener, or remove it if you want the socket to be the only FastCGI entry point.
|
||||||
|
|
||||||
@@ -350,6 +354,7 @@ Recommended deployment notes:
|
|||||||
|
|
||||||
- keep `HTTP_PORT` bound to localhost only at the firewall or by network policy; nginx should be the public entry point
|
- keep `HTTP_PORT` bound to localhost only at the firewall or by network policy; nginx should be the public entry point
|
||||||
- keep `BIN_DIRECTORY`, `TMP_UPLOAD_PATH`, and `SESSION_PATH` on writable local storage
|
- keep `BIN_DIRECTORY`, `TMP_UPLOAD_PATH`, and `SESSION_PATH` on writable local storage
|
||||||
|
- use `SESSION_COOKIE_SECURE=1` for HTTPS-only deployments; leave it `0` only for local/plain-HTTP development
|
||||||
- after editing `/etc/uce/settings.cfg`, restart `uce.service`
|
- after editing `/etc/uce/settings.cfg`, restart `uce.service`
|
||||||
|
|
||||||
### 4. Install and enable the systemd service
|
### 4. Install and enable the systemd service
|
||||||
@@ -362,8 +367,8 @@ scripts/systemd/manage-uce-service.sh setup
|
|||||||
|
|
||||||
That script:
|
That script:
|
||||||
|
|
||||||
- installs `scripts/systemd/uce.service` as `/etc/systemd/system/uce.service`
|
- installs `scripts/systemd/uce.service` as `/etc/systemd/system/uce.service`, rewriting the repository-root path in the unit to the checkout you ran it from
|
||||||
- installs `etc/uce/settings.cfg` to `/etc/uce/settings.cfg` if it does not already exist
|
- installs `etc/uce/settings.cfg` to `/etc/uce/settings.cfg` if it does not already exist, likewise rewriting checkout-root paths
|
||||||
- reloads systemd
|
- reloads systemd
|
||||||
- enables the service at boot
|
- enables the service at boot
|
||||||
- starts the runtime immediately
|
- starts the runtime immediately
|
||||||
|
|||||||
+33
-24
@@ -11,20 +11,20 @@ A typical deployment has four pieces:
|
|||||||
3. `uce.service`, a systemd service that builds/starts/restarts the runtime.
|
3. `uce.service`, a systemd service that builds/starts/restarts the runtime.
|
||||||
4. nginx or Apache as the public HTTP server.
|
4. nginx or Apache as the public HTTP server.
|
||||||
|
|
||||||
Recommended filesystem layout for a source checkout:
|
Recommended filesystem layout for a source checkout (replace paths as needed):
|
||||||
|
|
||||||
```text
|
```text
|
||||||
/opt/uce/ UCE repository/runtime root
|
/path/to/uce-root UCE repository/runtime root (for example `/opt/uce` or `/Code/uce.openfu.com/uce`)
|
||||||
/var/www/html/ public web root served by nginx/Apache
|
/var/www/html/ public web root served by nginx/Apache
|
||||||
/etc/uce/settings.cfg runtime configuration
|
/etc/uce/settings.cfg runtime configuration
|
||||||
/run/uce/fastcgi.sock FastCGI socket used by nginx/Apache
|
/run/uce/fastcgi.sock FastCGI socket used by nginx/Apache
|
||||||
/run/uce/cli.sock local CLI/admin/test socket
|
/run/uce/cli.sock local CLI/admin/test socket
|
||||||
/var/cache/uce/work generated source, wasm modules, caches
|
/var/cache/uce/work generated source, wasm modules, caches
|
||||||
/var/lib/uce/uploads multipart upload scratch space
|
/var/lib/uce/uploads multipart upload scratch space
|
||||||
/var/lib/uce/sessions session files
|
/var/lib/uce/sessions session files
|
||||||
```
|
```
|
||||||
|
|
||||||
For packaged installs, the runtime may live under `/usr/lib/uce` instead of `/opt/uce`. Keep the public web root at `/var/www/html` or another normal web-root path, not under the runtime source tree.
|
For packaged installs, the runtime may live under `/usr/lib/uce` instead of your checkout root. Keep the public web root at `/var/www/html` or another normal web-root path, not under the runtime source tree.
|
||||||
|
|
||||||
## Build requirements
|
## Build requirements
|
||||||
|
|
||||||
@@ -62,10 +62,11 @@ apt install -y nginx
|
|||||||
apt install -y apache2
|
apt install -y apache2
|
||||||
```
|
```
|
||||||
|
|
||||||
Build UCE from the repository root:
|
Build UCE from your repository root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/uce
|
repo_root=/path/to/uce-root
|
||||||
|
cd "$repo_root"
|
||||||
bash scripts/build_core_wasm.sh
|
bash scripts/build_core_wasm.sh
|
||||||
bash scripts/build_linux.sh
|
bash scripts/build_linux.sh
|
||||||
```
|
```
|
||||||
@@ -104,7 +105,8 @@ The expected directories are:
|
|||||||
Install the WASI SDK:
|
Install the WASI SDK:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/uce
|
repo_root=/path/to/uce-root
|
||||||
|
cd "$repo_root"
|
||||||
scripts/install_wasi_sdk.sh
|
scripts/install_wasi_sdk.sh
|
||||||
scripts/install_wasi_sdk.sh --check-only
|
scripts/install_wasi_sdk.sh --check-only
|
||||||
```
|
```
|
||||||
@@ -163,7 +165,7 @@ systemctl restart uce.service
|
|||||||
|
|
||||||
## Runtime configuration
|
## Runtime configuration
|
||||||
|
|
||||||
Create `/etc/uce/settings.cfg` from `etc/uce/settings.cfg` and adjust paths if your runtime is not under `/opt/uce`. Replace any checkout-specific paths such as `WASM_CORE_PATH` with `/opt/uce/bin/wasm/core.wasm` or your actual runtime path.
|
Create `/etc/uce/settings.cfg` from `etc/uce/settings.cfg` and adjust paths to your checkout root. Replace checkout-specific settings such as `WASM_CORE_PATH` with `<UCE_REPO_ROOT>/bin/wasm/core.wasm` or leave it relative to `COMPILER_SYS_PATH` as appropriate.
|
||||||
|
|
||||||
Minimum useful settings:
|
Minimum useful settings:
|
||||||
|
|
||||||
@@ -171,9 +173,12 @@ Minimum useful settings:
|
|||||||
BIN_DIRECTORY=/var/cache/uce/work
|
BIN_DIRECTORY=/var/cache/uce/work
|
||||||
TMP_UPLOAD_PATH=/var/lib/uce/uploads
|
TMP_UPLOAD_PATH=/var/lib/uce/uploads
|
||||||
SESSION_PATH=/var/lib/uce/sessions
|
SESSION_PATH=/var/lib/uce/sessions
|
||||||
|
SESSION_COOKIE_SECURE=1
|
||||||
|
|
||||||
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
||||||
|
FCGI_SOCKET_MODE=0666
|
||||||
CLI_SOCKET_PATH=/run/uce/cli.sock
|
CLI_SOCKET_PATH=/run/uce/cli.sock
|
||||||
|
CLI_SOCKET_MODE=0600
|
||||||
|
|
||||||
SITE_DIRECTORY=/var/www/html
|
SITE_DIRECTORY=/var/www/html
|
||||||
HTTP_DOCUMENT_ROOT=/var/www/html
|
HTTP_DOCUMENT_ROOT=/var/www/html
|
||||||
@@ -183,7 +188,7 @@ PROACTIVE_COMPILE_CHECK_INTERVAL=60
|
|||||||
|
|
||||||
WASM_COMPILE_SCRIPT=scripts/compile_wasm_unit
|
WASM_COMPILE_SCRIPT=scripts/compile_wasm_unit
|
||||||
WASM_BACKEND_VERBOSE=0
|
WASM_BACKEND_VERBOSE=0
|
||||||
WASM_CORE_PATH=/opt/uce/bin/wasm/core.wasm
|
WASM_CORE_PATH=<UCE_REPO_ROOT>/bin/wasm/core.wasm
|
||||||
WASM_MEMORY_LIMIT_BYTES=536870912
|
WASM_MEMORY_LIMIT_BYTES=536870912
|
||||||
WASM_EPOCH_DEADLINE_TICKS=200
|
WASM_EPOCH_DEADLINE_TICKS=200
|
||||||
WASM_EPOCH_PERIOD_MS=50
|
WASM_EPOCH_PERIOD_MS=50
|
||||||
@@ -199,11 +204,13 @@ WS_BROKER_OUTBOUND_TIMEOUT_SECONDS=30
|
|||||||
Important settings:
|
Important settings:
|
||||||
|
|
||||||
- `FCGI_SOCKET_PATH` is the Unix socket used for normal `.uce` requests. Set it explicitly and keep this value and the web-server `fastcgi_pass` path identical. The reference config uses `/run/uce/fastcgi.sock`; if you choose `/run/uce.sock`, use it in both places.
|
- `FCGI_SOCKET_PATH` is the Unix socket used for normal `.uce` requests. Set it explicitly and keep this value and the web-server `fastcgi_pass` path identical. The reference config uses `/run/uce/fastcgi.sock`; if you choose `/run/uce.sock`, use it in both places.
|
||||||
- `CLI_SOCKET_PATH` is a local HTTP-over-Unix socket used by `scripts/uce-cli` and test/admin units.
|
- `CLI_SOCKET_PATH` is a local HTTP-over-Unix socket used by `scripts/uce-cli` and test/admin units. Keep it private (`CLI_SOCKET_MODE=0600`) unless you intentionally delegate admin/test execution to a trusted Unix group (`0660`).
|
||||||
|
- `FCGI_SOCKET_MODE` and `CLI_SOCKET_MODE` are octal permission modes applied after socket bind. Prefer tightening `FCGI_SOCKET_MODE` to `0660` when nginx/Apache can share a trusted group with the UCE worker.
|
||||||
- `SITE_DIRECTORY` is the public site tree to scan for `.uce` files. Use `/var/www/html` when the web root is outside the runtime tree; relative paths are resolved from the runtime working directory.
|
- `SITE_DIRECTORY` is the public site tree to scan for `.uce` files. Use `/var/www/html` when the web root is outside the runtime tree; relative paths are resolved from the runtime working directory.
|
||||||
- `HTTP_DOCUMENT_ROOT` is the root used by the built-in HTTP/WebSocket listener when it resolves upgrade requests. Set it to the same web root as nginx/Apache.
|
- `HTTP_DOCUMENT_ROOT` is the root used by the built-in HTTP/WebSocket listener when it resolves upgrade requests. Set it to the same web root as nginx/Apache.
|
||||||
- `BIN_DIRECTORY` stores generated C++, wasm artifacts, compile output, and runtime caches.
|
- `BIN_DIRECTORY` stores generated C++, wasm artifacts, compile output, and runtime caches.
|
||||||
- `TMP_UPLOAD_PATH` and `SESSION_PATH` must be writable by the runtime.
|
- `TMP_UPLOAD_PATH` and `SESSION_PATH` must be writable by the runtime.
|
||||||
|
- `SESSION_COOKIE_SECURE=1` adds the `Secure` attribute to UCE-managed session cookies and should be used for HTTPS-only deployments. Leave it `0` only for local/plain-HTTP development.
|
||||||
- `HTTP_PORT` is the built-in HTTP/WebSocket listener used for WebSocket upgrade traffic and direct local probes. Bind/firewall it for local access only; nginx/Apache should be the public entry point.
|
- `HTTP_PORT` is the built-in HTTP/WebSocket listener used for WebSocket upgrade traffic and direct local probes. Bind/firewall it for local access only; nginx/Apache should be the public entry point.
|
||||||
- `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` controls how long a forwarded WS message can remain queued in the broker before being dropped (default `30`). Set to `0` to disable the timeout.
|
- `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` controls how long a forwarded WS message can remain queued in the broker before being dropped (default `30`). Set to `0` to disable the timeout.
|
||||||
- `WASM_COMPILE_SCRIPT` must point to `scripts/compile_wasm_unit` unless you provide an equivalent compiler. Relative paths are resolved from the runtime root/`COMPILER_SYS_PATH`. That script calls `scripts/check_unit_wasm.py` after linking each unit and uses the pinned WASI SDK on every deployment host.
|
- `WASM_COMPILE_SCRIPT` must point to `scripts/compile_wasm_unit` unless you provide an equivalent compiler. Relative paths are resolved from the runtime root/`COMPILER_SYS_PATH`. That script calls `scripts/check_unit_wasm.py` after linking each unit and uses the pinned WASI SDK on every deployment host.
|
||||||
@@ -220,11 +227,12 @@ systemctl restart uce.service
|
|||||||
For source-checkout deployments, install the provided service helper:
|
For source-checkout deployments, install the provided service helper:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/uce
|
repo_root=/path/to/uce-root
|
||||||
|
cd "$repo_root"
|
||||||
scripts/systemd/manage-uce-service.sh setup
|
scripts/systemd/manage-uce-service.sh setup
|
||||||
```
|
```
|
||||||
|
|
||||||
That helper installs `scripts/systemd/uce.service`, creates runtime directories, enables the service, and starts it.
|
That helper installs `scripts/systemd/uce.service` from your checked-out tree, rewrites the checked-out repository path into the installed unit and first-time config, creates runtime directories, enables the service, and starts it. Use a custom unit only if you need a nonstandard runtime layout.
|
||||||
|
|
||||||
Useful commands:
|
Useful commands:
|
||||||
|
|
||||||
@@ -234,7 +242,7 @@ scripts/systemd/manage-uce-service.sh restart
|
|||||||
scripts/systemd/manage-uce-service.sh logs 200
|
scripts/systemd/manage-uce-service.sh logs 200
|
||||||
```
|
```
|
||||||
|
|
||||||
Equivalent manual systemd service for a source checkout:
|
Equivalent manual systemd service for a source checkout (`<UCE_REPO>` = checkout root):
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
@@ -244,14 +252,14 @@ Wants=network-online.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/opt/uce
|
WorkingDirectory=<UCE_REPO>
|
||||||
RuntimeDirectory=uce
|
RuntimeDirectory=uce
|
||||||
StateDirectory=uce
|
StateDirectory=uce
|
||||||
CacheDirectory=uce
|
CacheDirectory=uce
|
||||||
ExecStartPre=/usr/bin/mkdir -p /var/cache/uce/work /var/lib/uce/uploads /var/lib/uce/sessions
|
ExecStartPre=/usr/bin/mkdir -p /var/cache/uce/work /var/lib/uce/uploads /var/lib/uce/sessions
|
||||||
ExecStartPre=/usr/bin/rm -f /run/uce/fastcgi.sock
|
ExecStartPre=/usr/bin/rm -f /run/uce/fastcgi.sock
|
||||||
ExecStartPre=/usr/bin/bash /opt/uce/scripts/build_linux.sh
|
ExecStartPre=/usr/bin/bash <UCE_REPO>/scripts/build_linux.sh
|
||||||
ExecStart=/opt/uce/bin/uce_fastcgi.linux.bin
|
ExecStart=<UCE_REPO>/bin/uce_fastcgi.linux.bin
|
||||||
ExecStopPost=/usr/bin/rm -f /run/uce/fastcgi.sock
|
ExecStopPost=/usr/bin/rm -f /run/uce/fastcgi.sock
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
@@ -584,7 +592,8 @@ curl -i http://127.0.0.1/examples/uce-starter/ -H 'Host: example.com'
|
|||||||
Check the local CLI path:
|
Check the local CLI path:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/uce
|
repo_root=/path/to/uce-root
|
||||||
|
cd "$repo_root"
|
||||||
scripts/uce-cli /tests/cli.uce action=echo message=hello
|
scripts/uce-cli /tests/cli.uce action=echo message=hello
|
||||||
scripts/run_cli_tests.sh
|
scripts/run_cli_tests.sh
|
||||||
```
|
```
|
||||||
@@ -615,7 +624,7 @@ PY
|
|||||||
## Operational footguns
|
## Operational footguns
|
||||||
|
|
||||||
- Keep the FastCGI socket path consistent: `FCGI_SOCKET_PATH` and the web-server `fastcgi_pass` must match exactly. The reference config uses `/run/uce/fastcgi.sock`; if you choose `/run/uce.sock`, use it in both places.
|
- Keep the FastCGI socket path consistent: `FCGI_SOCKET_PATH` and the web-server `fastcgi_pass` must match exactly. The reference config uses `/run/uce/fastcgi.sock`; if you choose `/run/uce.sock`, use it in both places.
|
||||||
- Keep the public web root separate from the runtime source tree. The examples use `/opt/uce` for runtime files and `/var/www/html` for public files.
|
- Keep the public web root separate from the runtime source tree. Replace `/opt/uce` with your actual checkout path in local examples (for example `/opt/uce` or `/Code/uce.openfu.com/uce`), and keep public files under `/var/www/html`.
|
||||||
- Set `HTTP_DOCUMENT_ROOT` when the web root is outside the runtime working directory. The built-in HTTP/WebSocket listener resolves upgrade paths from this setting.
|
- Set `HTTP_DOCUMENT_ROOT` when the web root is outside the runtime working directory. The built-in HTTP/WebSocket listener resolves upgrade paths from this setting.
|
||||||
- Do not expose `CLI_SOCKET_PATH` or `HTTP_PORT` as public entry points. The public path should be nginx/Apache.
|
- Do not expose `CLI_SOCKET_PATH` or `HTTP_PORT` as public entry points. The public path should be nginx/Apache.
|
||||||
- Do not trust `Script-Filename` request headers from direct HTTP clients. The built-in HTTP listener resolves from `HTTP_DOCUMENT_ROOT` and rejects `..` path segments.
|
- Do not trust `Script-Filename` request headers from direct HTTP clients. The built-in HTTP listener resolves from `HTTP_DOCUMENT_ROOT` and rejects `..` path segments.
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ gets invoked*.
|
|||||||
|
|
||||||
```
|
```
|
||||||
┌────────────────────────────┐
|
┌────────────────────────────┐
|
||||||
nginx ──FastCGI──► worker pool (N processes) │ /run/uce.sock
|
nginx ──FastCGI──► worker pool (N processes) │ $FCGI_SOCKET_PATH (example `/run/uce/fastcgi.sock`)
|
||||||
(port 80 etc.) │ uniform unit renderers │ (FastCGI + CLI)
|
(port 80 etc.) │ uniform unit renderers │ (FastCGI + CLI)
|
||||||
└─────────────▲──────────────┘
|
└─────────────▲──────────────┘
|
||||||
│ forward render (FastCGI, uce.sock)
|
│ forward render (FastCGI, FCGI_SOCKET_PATH)
|
||||||
│
|
│
|
||||||
browser ──raw HTTP / WS──► ┌────────┴─────────┐
|
browser ──raw HTTP / WS──► ┌────────┴─────────┐
|
||||||
(HTTP_PORT 8080) │ WS broker │ owns HTTP_PORT + every
|
(HTTP_PORT 8080) │ WS broker │ owns HTTP_PORT + every
|
||||||
@@ -48,14 +48,14 @@ gets invoked*.
|
|||||||
| Process | Owns | Renders units? | Source |
|
| Process | Owns | Renders units? | Source |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| **Parent** | nothing; supervises children | no | `main()`, `init_base_process()` |
|
| **Parent** | nothing; supervises children | no | `main()`, `init_base_process()` |
|
||||||
| **Worker** (×`WORKER_COUNT`) | `FCGI_SOCKET_PATH` (`/run/uce.sock`) + `CLI_SOCKET_PATH` | **yes** — the only processes that run wasm | `listen_for_connections()` |
|
| **Worker** (×`WORKER_COUNT`) | `FCGI_SOCKET_PATH` (configured socket path; example `/run/uce/fastcgi.sock`) + `CLI_SOCKET_PATH` | **yes** — the only processes that run wasm | `listen_for_connections()` |
|
||||||
| **WS broker** (×1) | `HTTP_PORT` + every live WS connection + `WS_BROKER_SOCKET_PATH` | no — forwards to the pool | `run_ws_broker()` |
|
| **WS broker** (×1) | `HTTP_PORT` + every live WS connection + `WS_BROKER_SOCKET_PATH` | no — forwards to the pool | `run_ws_broker()` |
|
||||||
| **serve_http dispatcher** (×bind) | one custom-server bind address | no — forwards to the pool | `custom_server_http_dispatcher_loop()` |
|
| **serve_http dispatcher** (×bind) | one custom-server bind address | no — forwards to the pool | `custom_server_http_dispatcher_loop()` |
|
||||||
| **Proactive compiler** | nothing; pre-compiles units | no | `run_proactive_compiler()` |
|
| **Proactive compiler** | nothing; pre-compiles units | no | `run_proactive_compiler()` |
|
||||||
|
|
||||||
**only workers instantiate Wasmtime and run unit code.**
|
**only workers instantiate Wasmtime and run unit code.**
|
||||||
Every connection-owning process (broker, serve_http dispatcher) forwards the
|
Every connection-owning process (broker, serve_http dispatcher) forwards the
|
||||||
request invocation back to a worker over `/run/uce.sock` using the minimal
|
request invocation back to a worker via `FCGI_SOCKET_PATH` using the minimal
|
||||||
FastCGI client in [`src/lib/fcgi_forward.h`](../src/lib/fcgi_forward.h). This is
|
FastCGI client in [`src/lib/fcgi_forward.h`](../src/lib/fcgi_forward.h). This is
|
||||||
forced by Wasmtime: an `Engine`/`Store` cannot be safely re-created across
|
forced by Wasmtime: an `Engine`/`Store` cannot be safely re-created across
|
||||||
`fork()`, and the brokers fork from the parent that already touched the
|
`fork()`, and the brokers fork from the parent that already touched the
|
||||||
@@ -137,7 +137,7 @@ Each request gets a fresh **workspace** — a per-request wasm instance tree wit
|
|||||||
the membrane wired in. `wasm_worker_serve(worker, ctx, entry_unit, handler)`
|
the membrane wired in. `wasm_worker_serve(worker, ctx, entry_unit, handler)`
|
||||||
(`src/wasm/worker.cpp`) is the single entry point for *every* mode:
|
(`src/wasm/worker.cpp`) is the single entry point for *every* mode:
|
||||||
|
|
||||||
1. Birth a workspace (CoW-snapshot-based where available).
|
1. Birth a request-scoped workspace with fresh per-request state. Current production workers instantiate a fresh workspace for each request; any future snapshot/CoW optimization must preserve that request-isolation contract.
|
||||||
2. Resolve `entry_unit` + `handler` to an export; components referenced at
|
2. Resolve `entry_unit` + `handler` to an export; components referenced at
|
||||||
runtime are resolved on demand via the `uce_host_component_resolve` hostcall
|
runtime are resolved on demand via the `uce_host_component_resolve` hostcall
|
||||||
(`component_resolve()` → `__uce_<...>` slot), loading dependency modules
|
(`component_resolve()` → `__uce_<...>` slot), loading dependency modules
|
||||||
@@ -158,8 +158,7 @@ Wasmtime's own trap signals are not escalated into a native fatal signal (see
|
|||||||
captures the current `WasmWorkspace*`, but `src/lib/sys.cpp::task()` invokes the
|
captures the current `WasmWorkspace*`, but `src/lib/sys.cpp::task()` invokes the
|
||||||
captured callback only in the forked child, before the hostcall stack unwinds in
|
captured callback only in the forked child, before the hostcall stack unwinds in
|
||||||
that child. The parent request may return and destroy its workspace; the child
|
that child. The parent request may return and destroy its workspace; the child
|
||||||
still has its own copy-on-write stack and its own copy of the per-request wasm
|
is forked from the parent and keeps a private request-context copy of the per-request workspace. This means a delayed task callback can run after the spawning request
|
||||||
workspace. This means a delayed task callback can run after the spawning request
|
|
||||||
returns without dereferencing the parent's destroyed workspace. It is still a
|
returns without dereferencing the parent's destroyed workspace. It is still a
|
||||||
callback into the inherited child workspace, not a fresh normal request
|
callback into the inherited child workspace, not a fresh normal request
|
||||||
workspace; avoid adding host resources to `WasmWorkspace` that are invalid across
|
workspace; avoid adding host resources to `WasmWorkspace` that are invalid across
|
||||||
@@ -182,7 +181,7 @@ otherwise (page) → serve_via_wasm(entry_unit, "render")
|
|||||||
|
|
||||||
The `UCE_*` params are set by whichever broker forwarded the request:
|
The `UCE_*` params are set by whichever broker forwarded the request:
|
||||||
|
|
||||||
- **Page render**: FastCGI nginx → `/run/uce.sock` directly; no `UCE_*` flags → `render`.
|
- **Page render**: FastCGI nginx → `FCGI_SOCKET_PATH` directly; no `UCE_*` flags → `render`.
|
||||||
- **CLI**: the CLI socket sets `is_cli`.
|
- **CLI**: the CLI socket sets `is_cli`.
|
||||||
- **serve_http**: the custom-server dispatcher sets `UCE_SERVE_HTTP=1` plus
|
- **serve_http**: the custom-server dispatcher sets `UCE_SERVE_HTTP=1` plus
|
||||||
`UCE_SERVE_HTTP_FUNCTION` and rewrites `SCRIPT_FILENAME` to the configured
|
`UCE_SERVE_HTTP_FUNCTION` and rewrites `SCRIPT_FILENAME` to the configured
|
||||||
@@ -218,7 +217,7 @@ broker loop:
|
|||||||
2. The message rides as `UCE_WS_MESSAGE` (base64) with an **empty STDIN body** —
|
2. The message rides as `UCE_WS_MESSAGE` (base64) with an **empty STDIN body** —
|
||||||
a non-empty STDIN makes the FastCGI transport flush a premature response
|
a non-empty STDIN makes the FastCGI transport flush a premature response
|
||||||
before `on_complete` ever runs.
|
before `on_complete` ever runs.
|
||||||
3. Connect to `/run/uce.sock` (non-blocking) and queue the encoded request in
|
3. Connect to `FCGI_SOCKET_PATH` (non-blocking) and queue the encoded request in
|
||||||
`ws_broker_outbound[fd]` with an enqueue timestamp.
|
`ws_broker_outbound[fd]` with an enqueue timestamp.
|
||||||
|
|
||||||
`ws_broker_drain_outbound()` runs after every `process(50)` tick: it finishes
|
`ws_broker_drain_outbound()` runs after every `process(50)` tick: it finishes
|
||||||
@@ -310,8 +309,10 @@ header free-functions are `inline`. The wasm backend exposes only declarations
|
|||||||
| Key | Default | Meaning |
|
| Key | Default | Meaning |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `WASM_BACKEND_VERBOSE` | `0` | Emit `X-UCE-Wasm-*` workspace timing headers (benchmark only). |
|
| `WASM_BACKEND_VERBOSE` | `0` | Emit `X-UCE-Wasm-*` workspace timing headers (benchmark only). |
|
||||||
| `FCGI_SOCKET_PATH` | `/run/uce.sock` | Worker pool FastCGI socket (brokers forward here). |
|
| `FCGI_SOCKET_PATH` | runtime-configured (`/run/uce/fastcgi.sock` in this doc) | Worker pool FastCGI socket (brokers forward here). |
|
||||||
| `CLI_SOCKET_PATH` | `/run/uce/cli.sock` | Worker CLI socket. |
|
| `CLI_SOCKET_PATH` | `/run/uce/cli.sock` | Worker CLI/admin socket. Keep private; reference `CLI_SOCKET_MODE` is `0600`. |
|
||||||
|
| `FCGI_SOCKET_MODE` | `0666` | Permission mode applied to `FCGI_SOCKET_PATH` after bind; set tighter if nginx/Apache can use a trusted group. |
|
||||||
|
| `CLI_SOCKET_MODE` | `0600` | Permission mode applied to `CLI_SOCKET_PATH`; set `0660` only for a trusted admin group. |
|
||||||
| `HTTP_PORT` | `8080` | Raw HTTP + WebSocket port — owned by the WS broker. |
|
| `HTTP_PORT` | `8080` | Raw HTTP + WebSocket port — owned by the WS broker. |
|
||||||
| `WS_BROKER_SOCKET_PATH` | `/run/uce/ws-broker.sock` | Broker command socket for `ws_*` flushes. |
|
| `WS_BROKER_SOCKET_PATH` | `/run/uce/ws-broker.sock` | Broker command socket for `ws_*` flushes. |
|
||||||
| `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` | `30` | Max lifetime in seconds for queued WS broker forwards before drop. |
|
| `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` | `30` | Max lifetime in seconds for queued WS broker forwards before drop. |
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ SESSION_PATH=/var/lib/uce/sessions
|
|||||||
|
|
||||||
# LISTEN ON SOCKETS
|
# LISTEN ON SOCKETS
|
||||||
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
FCGI_SOCKET_PATH=/run/uce/fastcgi.sock
|
||||||
|
# FastCGI is normally consumed by the local web server user/group.
|
||||||
|
FCGI_SOCKET_MODE=0666
|
||||||
FCGI_PORT=9993
|
FCGI_PORT=9993
|
||||||
|
|
||||||
# HTTP-over-Unix command socket for local CLI/control tooling.
|
# HTTP-over-Unix command socket for local CLI/control tooling.
|
||||||
# Example: curl --unix-socket /run/uce/cli.sock http://localhost/ping
|
# Example: curl --unix-socket /run/uce/cli.sock http://localhost/ping
|
||||||
CLI_SOCKET_PATH=/run/uce/cli.sock
|
CLI_SOCKET_PATH=/run/uce/cli.sock
|
||||||
|
# Keep the CLI/admin socket private by default; set 0660 only for a trusted group.
|
||||||
|
CLI_SOCKET_MODE=0600
|
||||||
|
|
||||||
# Built-in HTTP/WebSocket listener used for WebSocket Upgrade requests.
|
# Built-in HTTP/WebSocket listener used for WebSocket Upgrade requests.
|
||||||
# Keep this behind nginx/Apache on localhost or firewall it from public access.
|
# Keep this behind nginx/Apache on localhost or firewall it from public access.
|
||||||
@@ -34,7 +38,7 @@ WASM_COMPILE_SCRIPT=scripts/compile_wasm_unit
|
|||||||
|
|
||||||
# WASM RUNTIME SETTINGS. Unit execution is always routed through wasm.
|
# WASM RUNTIME SETTINGS. Unit execution is always routed through wasm.
|
||||||
WASM_BACKEND_VERBOSE=0
|
WASM_BACKEND_VERBOSE=0
|
||||||
WASM_CORE_PATH=/Code/uce.openfu.com/uce/bin/wasm/core.wasm
|
WASM_CORE_PATH=bin/wasm/core.wasm
|
||||||
WASM_MEMORY_LIMIT_BYTES=536870912
|
WASM_MEMORY_LIMIT_BYTES=536870912
|
||||||
WASM_EPOCH_DEADLINE_TICKS=200
|
WASM_EPOCH_DEADLINE_TICKS=200
|
||||||
WASM_EPOCH_PERIOD_MS=50
|
WASM_EPOCH_PERIOD_MS=50
|
||||||
@@ -85,6 +89,8 @@ ARCHIVE_MAX_ZIP_ENTRIES=4096
|
|||||||
|
|
||||||
# LIFETIME OF SESSION COOKIES IN SECONDS
|
# LIFETIME OF SESSION COOKIES IN SECONDS
|
||||||
SESSION_TIME=2592000
|
SESSION_TIME=2592000
|
||||||
|
# Set to 1 behind HTTPS-only frontends to add Secure to session cookies.
|
||||||
|
SESSION_COOKIE_SECURE=0
|
||||||
|
|
||||||
# DEVELOPER-DEFINED ERROR PAGES (see /doc/index.uce?p=error_pages and
|
# DEVELOPER-DEFINED ERROR PAGES (see /doc/index.uce?p=error_pages and
|
||||||
# /doc/index.uce?p=3_blocked_functions). The unit receives the error details in
|
# /doc/index.uce?p=3_blocked_functions). The unit receives the error details in
|
||||||
|
|||||||
@@ -19,10 +19,23 @@ CONFIG_DEST="/etc/uce/settings.cfg"
|
|||||||
|
|
||||||
action="${1:-setup}"
|
action="${1:-setup}"
|
||||||
|
|
||||||
|
render_runtime_file() {
|
||||||
|
local source="$1"
|
||||||
|
local destination="$2"
|
||||||
|
local mode="$3"
|
||||||
|
local tmp
|
||||||
|
tmp="$(mktemp)"
|
||||||
|
trap 'rm -f "$tmp"' RETURN
|
||||||
|
sed "s#/Code/uce.openfu.com/uce#$REPO_ROOT#g" "$source" > "$tmp"
|
||||||
|
install -D -m "$mode" "$tmp" "$destination"
|
||||||
|
rm -f "$tmp"
|
||||||
|
trap - RETURN
|
||||||
|
}
|
||||||
|
|
||||||
install_unit() {
|
install_unit() {
|
||||||
install -D -m 0644 "$UNIT_SOURCE" "$UNIT_DEST"
|
render_runtime_file "$UNIT_SOURCE" "$UNIT_DEST" 0644
|
||||||
if [[ ! -f "$CONFIG_DEST" ]]; then
|
if [[ ! -f "$CONFIG_DEST" ]]; then
|
||||||
install -D -m 0644 "$CONFIG_SOURCE" "$CONFIG_DEST"
|
render_runtime_file "$CONFIG_SOURCE" "$CONFIG_DEST" 0644
|
||||||
fi
|
fi
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ session_name : the name of the session
|
|||||||
>session
|
>session
|
||||||
|
|
||||||
:content
|
:content
|
||||||
Deletes the cookie specified by `session_name` and clears the data stored under the current session ID.
|
Deletes the cookie specified by `session_name`, removes the matching server-side session file, and clears the data stored under the current session ID.
|
||||||
|
|
||||||
This also empties `context.session_id` and `context.session`.
|
This also empties `context.session_id`, `context.session_name`, and `context.session`.
|
||||||
|
|
||||||
|
|
||||||
:example
|
:example
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ return value : the current session ID
|
|||||||
:content
|
:content
|
||||||
Starts a session or reconnects to an existing one.
|
Starts a session or reconnects to an existing one.
|
||||||
|
|
||||||
If the cookie named by `session_name` does not exist, UCE creates it and fills it with a new unique session ID. The function then loads the session data for that ID.
|
If the cookie named by `session_name` does not exist, UCE creates it and fills it with a new unique session ID. The function then loads the session data for that ID. Session cookies are emitted with `Path=/`, `HttpOnly`, `SameSite=Lax`, and `Secure` when `SESSION_COOKIE_SECURE=1` is set in the runtime config.
|
||||||
|
|
||||||
After `session_start()` completes, the following `context` fields are populated:
|
After `session_start()` completes, the following `context` fields are populated:
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
u64 socket_connect(String host, u16 port)
|
u64 socket_connect(String host, u16 port)
|
||||||
|
|
||||||
:params
|
:params
|
||||||
host : host name
|
host : IPv4 address (for example `127.0.0.1`), as a dotted-quad string
|
||||||
port : port number
|
port : port number
|
||||||
return value : the socket handle
|
return value : the socket handle
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ return value : the socket handle
|
|||||||
:content
|
:content
|
||||||
Opens a socket connection to the given `host` and `port`.
|
Opens a socket connection to the given `host` and `port`.
|
||||||
|
|
||||||
The returned socket handle is then used with `socket_read()`, `socket_write()`, and `socket_close()`.
|
The returned socket handle is then used with `socket_read()`, `socket_write()`, and `socket_close()`. Currently this helper accepts IPv4 dotted-quad addresses in socket calls and does not perform hostname resolution.
|
||||||
|
|
||||||
:example
|
:example
|
||||||
u64 fd = socket_connect("127.0.0.1", 80);
|
u64 fd = socket_connect("127.0.0.1", 80);
|
||||||
|
|||||||
+3
-2
@@ -17,8 +17,9 @@ RENDER(Request& context)
|
|||||||
|
|
||||||
String action = first(context.get["action"], "touch");
|
String action = first(context.get["action"], "touch");
|
||||||
String session_id = session_start("uce-site-tests");
|
String session_id = session_start("uce-site-tests");
|
||||||
|
String session_path = context.server->config["SESSION_PATH"] + "/" + session_id;
|
||||||
if(action == "destroy")
|
if(action == "destroy")
|
||||||
session_destroy();
|
session_destroy("uce-site-tests");
|
||||||
else
|
else
|
||||||
context.session["suite"] = "http";
|
context.session["suite"] = "http";
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ RENDER(Request& context)
|
|||||||
check("session_id_create()", generated_session.length() >= 16, generated_session);
|
check("session_id_create()", generated_session.length() >= 16, generated_session);
|
||||||
|
|
||||||
if(action == "destroy")
|
if(action == "destroy")
|
||||||
check("session_destroy()", session_dump.find("suite") == String::npos, session_dump);
|
check("session_destroy()", session_dump.find("suite") == String::npos && context.session_id == "" && context.session_name == "" && !file_exists(session_path), session_dump + " path=" + session_path);
|
||||||
else
|
else
|
||||||
check("context.session writes", context.session["suite"] == "http", session_dump);
|
check("context.session writes", context.session["suite"] == "http", session_dump);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// Minimal FastCGI client used by the connection brokers (the custom HTTP server
|
// Minimal FastCGI client used by the connection brokers (the custom HTTP server
|
||||||
// dispatcher and the websocket exec child) to render a request through a normal
|
// dispatcher and the websocket exec child) to render a request through a normal
|
||||||
// worker on /run/uce.sock instead of rendering wasm in the broker's own forked
|
// worker on FCGI_SOCKET_PATH instead of rendering wasm in the broker's own forked
|
||||||
// process. Wasmtime cannot be safely re-created across fork, so the broker owns
|
// process. Wasmtime cannot be safely re-created across fork, so the broker owns
|
||||||
// the connection but forwards the actual unit invocation to a clean-engine
|
// the connection but forwards the actual unit invocation to a clean-engine
|
||||||
// worker — the "broker holds connections, units respond like RENDER()" model.
|
// worker — the "broker holds connections, units respond like RENDER()" model.
|
||||||
|
|||||||
+22
-5
@@ -876,7 +876,6 @@ String shell_exec(String cmd)
|
|||||||
|
|
||||||
String shell_escape(String raw)
|
String shell_escape(String raw)
|
||||||
{
|
{
|
||||||
// FIXME
|
|
||||||
String result = "";
|
String result = "";
|
||||||
for(auto c : raw)
|
for(auto c : raw)
|
||||||
{
|
{
|
||||||
@@ -971,8 +970,12 @@ bool path_is_within(String path, String root)
|
|||||||
|
|
||||||
bool mkdir(String path)
|
bool mkdir(String path)
|
||||||
{
|
{
|
||||||
shell_exec(String("mkdir -p ")+" "+shell_escape(path));
|
if(path == "")
|
||||||
return(true);
|
return(false);
|
||||||
|
std::error_code ec;
|
||||||
|
if(std::filesystem::exists(path, ec))
|
||||||
|
return(std::filesystem::is_directory(path, ec));
|
||||||
|
return(std::filesystem::create_directories(path, ec) || std::filesystem::is_directory(path, ec));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool file_exists(String path)
|
bool file_exists(String path)
|
||||||
@@ -1605,7 +1608,18 @@ void on_child_exit(int sig)
|
|||||||
|
|
||||||
StringList ls(String dir)
|
StringList ls(String dir)
|
||||||
{
|
{
|
||||||
return(split(trim(shell_exec("ls -1 "+shell_escape(dir))), "\n"));
|
StringList entries;
|
||||||
|
std::error_code ec;
|
||||||
|
if(!std::filesystem::is_directory(dir, ec))
|
||||||
|
return(entries);
|
||||||
|
for(auto const& entry : std::filesystem::directory_iterator(dir, ec))
|
||||||
|
{
|
||||||
|
if(ec)
|
||||||
|
break;
|
||||||
|
entries.push_back(entry.path().filename().string());
|
||||||
|
}
|
||||||
|
std::sort(entries.begin(), entries.end());
|
||||||
|
return(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringMap make_server_settings()
|
StringMap make_server_settings()
|
||||||
@@ -1622,8 +1636,10 @@ StringMap make_server_settings()
|
|||||||
cfg["SETUP_TEMPLATE"] = "scripts/setup.h.template";
|
cfg["SETUP_TEMPLATE"] = "scripts/setup.h.template";
|
||||||
cfg["LIT_ESC"] = "3d5b5_1";
|
cfg["LIT_ESC"] = "3d5b5_1";
|
||||||
cfg["CONTENT_TYPE"] = "text/html; charset=utf-8";
|
cfg["CONTENT_TYPE"] = "text/html; charset=utf-8";
|
||||||
cfg["FCGI_SOCKET_PATH"] = "/run/uce.sock";
|
cfg["FCGI_SOCKET_PATH"] = "/run/uce/fastcgi.sock";
|
||||||
|
cfg["FCGI_SOCKET_MODE"] = "0666";
|
||||||
cfg["CLI_SOCKET_PATH"] = "/run/uce/cli.sock";
|
cfg["CLI_SOCKET_PATH"] = "/run/uce/cli.sock";
|
||||||
|
cfg["CLI_SOCKET_MODE"] = "0600";
|
||||||
// Command socket the WS broker listens on; workers flush ws_* dispatch
|
// Command socket the WS broker listens on; workers flush ws_* dispatch
|
||||||
// command batches here at workspace teardown.
|
// command batches here at workspace teardown.
|
||||||
cfg["WS_BROKER_SOCKET_PATH"] = "/run/uce/ws-broker.sock";
|
cfg["WS_BROKER_SOCKET_PATH"] = "/run/uce/ws-broker.sock";
|
||||||
@@ -1632,6 +1648,7 @@ StringMap make_server_settings()
|
|||||||
cfg["UCE_HOSTCALL_BLOCKLIST"] = "";
|
cfg["UCE_HOSTCALL_BLOCKLIST"] = "";
|
||||||
cfg["TMP_UPLOAD_PATH"] = "/tmp/uce/uploads";
|
cfg["TMP_UPLOAD_PATH"] = "/tmp/uce/uploads";
|
||||||
cfg["SESSION_PATH"] = "/tmp/uce/sessions";
|
cfg["SESSION_PATH"] = "/tmp/uce/sessions";
|
||||||
|
cfg["SESSION_COOKIE_SECURE"] = "0";
|
||||||
cfg["COMPILER_SYS_PATH"] = ".";
|
cfg["COMPILER_SYS_PATH"] = ".";
|
||||||
cfg["PRECOMPILE_FILES_IN"] = "";
|
cfg["PRECOMPILE_FILES_IN"] = "";
|
||||||
cfg["SITE_DIRECTORY"] = "site";
|
cfg["SITE_DIRECTORY"] = "site";
|
||||||
|
|||||||
+18
-6
@@ -843,7 +843,8 @@ String session_start(String session_name)
|
|||||||
if(session_id.length() == 0)
|
if(session_id.length() == 0)
|
||||||
{
|
{
|
||||||
session_id = session_id_create();
|
session_id = session_id_create();
|
||||||
set_cookie(session_name, session_id, time() + int_val(context->server->config["SESSION_TIME"]));
|
bool secure_cookie = context->server->config["SESSION_COOKIE_SECURE"] == "1";
|
||||||
|
set_cookie(session_name, session_id, time() + int_val(context->server->config["SESSION_TIME"]), "/", "", secure_cookie, true);
|
||||||
}
|
}
|
||||||
context->session_id = session_id;
|
context->session_id = session_id;
|
||||||
context->session_name = session_name;
|
context->session_name = session_name;
|
||||||
@@ -856,12 +857,23 @@ String session_start(String session_name)
|
|||||||
|
|
||||||
void session_destroy(String session_name)
|
void session_destroy(String session_name)
|
||||||
{
|
{
|
||||||
if(context->cookies[session_name].length() > 0)
|
String cookie_session_id = context->cookies[session_name];
|
||||||
|
String active_session_id = context->session_name == session_name ? context->session_id : "";
|
||||||
|
String destroy_session_id = active_session_id != "" ? active_session_id : cookie_session_id;
|
||||||
|
if(cookie_session_id.length() > 0 || active_session_id.length() > 0)
|
||||||
{
|
{
|
||||||
set_cookie(session_name, "", time() - int_val(context->server->config["SESSION_TIME"]));
|
bool secure_cookie = context->server->config["SESSION_COOKIE_SECURE"] == "1";
|
||||||
context->session.clear();
|
set_cookie(session_name, "", time() - int_val(context->server->config["SESSION_TIME"]), "/", "", secure_cookie, true);
|
||||||
save_session_data(context->session_id, context->session);
|
String session_path = session_file_path(destroy_session_id);
|
||||||
context->session_id = "";
|
if(session_path != "")
|
||||||
|
file_unlink(session_path);
|
||||||
|
if(active_session_id != "")
|
||||||
|
{
|
||||||
|
context->session.clear();
|
||||||
|
context->session_loaded_hash = session_hash_serialized(session_serialize(context->session));
|
||||||
|
context->session_id = "";
|
||||||
|
context->session_name = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-2
@@ -1353,6 +1353,27 @@ void listen_for_connections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode_t configured_socket_mode(String value, mode_t fallback)
|
||||||
|
{
|
||||||
|
value = trim(value);
|
||||||
|
if(value == "")
|
||||||
|
return(fallback);
|
||||||
|
char* end = 0;
|
||||||
|
long parsed = strtol(value.c_str(), &end, 8);
|
||||||
|
if(end == value.c_str() || *end != '\0' || parsed < 0 || parsed > 0777)
|
||||||
|
return(fallback);
|
||||||
|
return((mode_t)parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void chmod_configured_socket(String path, String mode_value, mode_t fallback)
|
||||||
|
{
|
||||||
|
if(path == "")
|
||||||
|
return;
|
||||||
|
mode_t mode = configured_socket_mode(mode_value, fallback);
|
||||||
|
if(chmod(path.c_str(), mode) != 0)
|
||||||
|
fprintf(stderr, "(!) Could not chmod socket %s to %04o: %s\n", path.c_str(), (unsigned int)mode, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
void init_base_process()
|
void init_base_process()
|
||||||
{
|
{
|
||||||
printf("(P) Starting parent server PID:%i\n", getpid());
|
printf("(P) Starting parent server PID:%i\n", getpid());
|
||||||
@@ -1369,13 +1390,13 @@ void init_base_process()
|
|||||||
if(server_state.config["FCGI_SOCKET_PATH"] != "")
|
if(server_state.config["FCGI_SOCKET_PATH"] != "")
|
||||||
{
|
{
|
||||||
server.listen(server_state.config["FCGI_SOCKET_PATH"]);
|
server.listen(server_state.config["FCGI_SOCKET_PATH"]);
|
||||||
chmod(server_state.config["FCGI_SOCKET_PATH"].c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
chmod_configured_socket(server_state.config["FCGI_SOCKET_PATH"], server_state.config["FCGI_SOCKET_MODE"], 0666);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(server_state.config["CLI_SOCKET_PATH"] != "")
|
if(server_state.config["CLI_SOCKET_PATH"] != "")
|
||||||
{
|
{
|
||||||
server.listen_cli(server_state.config["CLI_SOCKET_PATH"]);
|
server.listen_cli(server_state.config["CLI_SOCKET_PATH"]);
|
||||||
chmod(server_state.config["CLI_SOCKET_PATH"].c_str(), S_IRWXU | S_IRGRP | S_IWGRP);
|
chmod_configured_socket(server_state.config["CLI_SOCKET_PATH"], server_state.config["CLI_SOCKET_MODE"], 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP_PORT (WebSocket + raw HTTP) is owned by the dedicated WS broker, not
|
// HTTP_PORT (WebSocket + raw HTTP) is owned by the dedicated WS broker, not
|
||||||
|
|||||||
Reference in New Issue
Block a user