12 releases
Uses new Rust 2024
new 0.1.4 | May 1, 2025 |
---|---|
0.1.3 | May 1, 2025 |
0.1.0 |
|
0.0.8 | Apr 30, 2025 |
#398 in Web programming
593 downloads per month
115KB
2K
SLoC
Foxy π¦
A minimal, configuration-driven, hyper-extendible Rust HTTP proxy library.
Features
- π£οΈ Powerful Routing: Predicate-based routing with path patterns, HTTP methods, headers, and query matching
- π Flexible Filters: Pre and post-processing filters for request/response modification
- βοΈ Configuration Superpowers: Layered configuration from files and environment variables
- π Fine-grained Control: Route-specific filter chains for precise request handling
- π Pluggable Security Chain β configurable, provider-based request authentication with built-in providers
- π Modern Async Architecture: Built on Tokio and Hyper for high performance
- π¦ Lightweight Dependencies: Minimal external dependencies for core functionality
- π§© Highly Extensible: Custom predicates, filters and security providers via simple traits
Quickstart
Run the basic proxy example
git clone https://github.com/johan-steffens/foxy.git
cd foxy
cargo run --example basic-proxy
Run it in your code
Add Foxy as a dependency to your Cargo.toml
file
[dependencies]
foxy-io = "..."
Build an instance and start the server.
use foxy::Foxy;
// Create a new Foxy instance with layered configuration
let foxy = Foxy::loader()
.with_env_vars() // Environment variables (highest priority)
.with_config_file("config.toml") // File-based config (medium priority)
.with_config_file("defaults.toml") // Defaults (lowest priority)
.build().await?;
// Start the proxy server and wait for it to complete
foxy.start().await?;
Core Principles
- Predictable Routing: Predicate-based matching with clear priorities determines how requests are routed
- Configurable Processing: Route-specific and global filters for request/response modification
- Extensibility: Trait-based design enables custom predicates and filters
- Configuration-Driven: All behavior controlled via flexible configuration with sensible defaults
Configuration
Foxy's power comes from its rich configuration system. Here's a brief overview:
{
"routes": [
{
"id": "api-route",
"target": "https://api.example.com",
"filters": [
{
"type": "path_rewrite",
"config": {
"pattern": "^/api/(.*)$",
"replacement": "/v2/$1"
}
}
],
"predicates": [
{
"type_": "path",
"config": {
"pattern": "/api/*"
}
}
]
}
]
}
For detailed information on all configuration options, see the Configuration Guide.
Configuration Sources
Foxy supports multiple configuration sources with priority order:
// Build a layered configuration
let foxy = Foxy::loader()
.with_env_vars() // First priority
.with_config_file("config.json") // Second priority
.build().await?;
Example: FOXY_SERVER_PORT=8080
β server.port
Enabling security
Add a security_chain
with a configured provider to your proxy configuration:
{
"proxy": {
"security_chain": [
{
"type": "oidc",
"config": {
"issuer-uri": "https://id.example.com/.well-known/openid-configuration",
"aud": "my-api",
"bypass-routes": [
{ "methods": ["GET"], "path": "/health" }
]
}
}
]
}
}
Thatβs it β requests hitting /api/**
will be validated against the IDP while /health
remains public.
Full configuration examples can be found in the Configuration Guide.
Streaming bodies
- Foxy proxies request and response bodies as streams end-to-end to ensure there's no full body buffering in memory.
- Large uploads/downloads back-pressure correctly.
- Memory usage is bound only by socket buffers.
Detailed timing metrics
- Foxy records and logs three high-resolution latencies on every call
(DEBUG level):
[timing] <METHOD> <PATH> -> <STATUS> | total=<X> upstream=<Y> internal=<Z>
field | description |
---|---|
total | wall-clock time from first byte in to last byte out |
upstream | time spent awaiting the target server |
internal | proxy-side routing / filtering / logging (total β upstream) |
Request and Response body logging
LoggingFilter
peeks and logs the first 1 000 bytes/characters of every request and response body (UTF-8-lossy).- Binary or very large payloads are safeβthe remainder of the stream is forwarded untouched.
- Please note: enabling request and response logging will introduce additional latency to your calls.
Development Status
- Configuration System
- Loader Module
- Core HTTP Proxy
- Predicate-based Routing
- Request/Response Filters
- Security Chain
- OIDC provider
- Basic auth provider
License
This project is licensed under Mozilla Public License Version 2.0
Dependencies
~17β36MB
~625K SLoC