diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a49610e..6370671 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,9 +46,14 @@ jobs: - name: Cache cargo and build uses: Swatinem/rust-cache@v2 - - name: Run tests + - name: Run tests (all features) run: cargo test --all-features --verbose --locked + - name: Run tests (minimal feature set) + # Verifies that `api` and `metrics` are truly optional: core proxy + + # tls + logging must compile and pass without them. + run: cargo test --no-default-features --features cli,tls,logging --verbose --locked + build: name: Build (release) runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f6fb5..c3dc08f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +_No unreleased changes yet._ + +## [0.5.0] - 2026-06-16 + ### Added - **Prometheus metrics** (optional `metrics` feature): request counters, latency @@ -199,6 +203,7 @@ localhost:8080 { - GitHub Release creation - Example programs for library usage +[0.5.0]: https://github.com/denislituev/tiny-proxy/releases/tag/v0.5.0 [0.4.0]: https://github.com/denislituev/tiny-proxy/releases/tag/v0.4.0 [0.3.0]: https://github.com/denislituev/tiny-proxy/releases/tag/v0.3.0 [0.2.0]: https://github.com/denislituev/tiny-proxy/releases/tag/v0.2.0 diff --git a/Cargo.lock b/Cargo.lock index 3d745b5..abf88d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1396,7 +1396,7 @@ checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "tiny-proxy" -version = "0.4.0" +version = "0.5.0" dependencies = [ "anyhow", "arc-swap", diff --git a/Cargo.toml b/Cargo.toml index 20dbeda..2e53dc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tiny-proxy" -version = "0.4.0" +version = "0.5.0" edition = "2021" description = "A high-performance HTTP reverse proxy server written in Rust with SSE support, connection pooling, and configurable routing" license = "MIT OR Apache-2.0" diff --git a/README.md b/README.md index 54ec16c..81d4f99 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Add to your `Cargo.toml`: ```toml [dependencies] -tiny-proxy = "0.4" +tiny-proxy = "0.5" ``` ## Docker @@ -114,6 +114,12 @@ tiny-proxy --config config.conf --addr 127.0.0.1:8080 TLS sites → HTTPS with SNI; non-TLS → HTTP. In auto-detect mode only, each TLS port also gets an HTTP→HTTPS redirect listener (`redirect_port = tls_port - 443 + 80`, e.g. 443→80, 8443→8080). With `--addr`, only the specified listener runs — **no** automatic redirect server. +- `--metrics-addr`: Optional. Address for the Prometheus metrics admin server (requires the + `metrics` feature). Can also be set via the `TINY_PROXY_METRICS_ADDR` environment variable. + Example: `--metrics-addr 127.0.0.1:9090` then `curl http://127.0.0.1:9090/metrics`. +- `--max-concurrency`: Max concurrent connections (default: CPU cores × 256, `0` for default). +- `--enable-api`: Enable management API server (requires the `api` feature). +- `--api-addr`: Address for API server (default: `127.0.0.1:8081`). ### Library Mode @@ -488,23 +494,23 @@ Use placeholders in `header` and `header_up` values: ```toml # Minimal - core HTTP proxy with HTTPS backend support (for embedding) [dependencies] -tiny-proxy = { version = "0.4", default-features = false } +tiny-proxy = { version = "0.5", default-features = false } # With frontend TLS termination [dependencies] -tiny-proxy = { version = "0.4", default-features = false, features = ["tls"] } +tiny-proxy = { version = "0.5", default-features = false, features = ["tls"] } # With management API [dependencies] -tiny-proxy = { version = "0.4", default-features = false, features = ["tls", "api"] } +tiny-proxy = { version = "0.5", default-features = false, features = ["tls", "api"] } # With Prometheus metrics [dependencies] -tiny-proxy = { version = "0.4", default-features = false, features = ["metrics"] } +tiny-proxy = { version = "0.5", default-features = false, features = ["metrics"] } # Full standalone (same as default) [dependencies] -tiny-proxy = "0.4" +tiny-proxy = "0.5" ``` #### `cli` (default) diff --git a/docker-compose.yml b/docker-compose.yml index c06023a..67a277c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,6 +22,11 @@ services: ports: - "8443:8443" # HTTPS (TLS termination) - "8080:8080" # HTTP → HTTPS redirect + # Prometheus metrics (built with --all-features in the Dockerfile): + # uncomment to scrape :9090/metrics from the host. + # - "9090:9090" + environment: + # TINY_PROXY_METRICS_ADDR: "0.0.0.0:9090" volumes: - ./config.conf:/etc/tiny-proxy/config.conf:ro - ./certs:/etc/ssl/tiny-proxy:ro diff --git a/examples/metrics.caddy b/examples/metrics.caddy new file mode 100644 index 0000000..f1581d0 --- /dev/null +++ b/examples/metrics.caddy @@ -0,0 +1,38 @@ +# Example: Prometheus metrics + multi-host upstream +# +# Run with: +# tiny-proxy --config examples/metrics.caddy --metrics-addr 127.0.0.1:9090 +# +# Then scrape the metrics endpoint: +# curl http://127.0.0.1:9090/metrics + +# Local site, proxied to an external HTTPS API with a different Host. +# {upstream_host} sets Host to the backend hostname (api.example.com), +# not the public-facing one (localhost:8080). +localhost:8080 { + reverse_proxy https://api.example.com:443 { + connect_timeout 10s + read_timeout 30s + # Override Host so the backend sees its own hostname + header_up Host {upstream_host} + # Preserve the original request URI (path + query) + header_up X-Original-Uri {request.uri} + # Forward the real client IP + header_up X-Real-IP {remote_ip} + # Strip Accept-Encoding so the backend doesn't compress the response + header_up -Accept-Encoding + } +} + +# TLS site with health-check + direct response +0.0.0.0:8443 { + tls /path/to/cert.pem /path/to/key.pem + + handle_path /health { + respond 200 "ok" + } + + reverse_proxy http://backend:3000 { + read_timeout 60s + } +}