Skip to content

Commit c9156d9

Browse files
committed
feat!: proxy-wasm edge-security-filter + Varnish 9 CI
- Add edge-security-filter module (bot detection, geo-blocking, rate limiting, header enrichment, metrics) - Fix memory corruption: use WS_Copy for http_SetHeader in Varnish 9 - CI: single Varnish 9.0.3 build (no matrix), lint + test + binary size check - Bump Docker base to varnish:9.0.3 - Add Cargo workspace for all Wasm examples - Remove incompatible HTTP callout (proxy-wasm SDK RefCell limitation) - All 19 VTC tests pass BREAKING CHANGE: Minimum Varnish version is now 9.0.3
1 parent 35830ae commit c9156d9

39 files changed

Lines changed: 2498 additions & 213 deletions

.editorconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = space
9+
indent_size = 4
10+
11+
[*.{yml,yaml}]
12+
indent_size = 2
13+
14+
[*.md]
15+
trim_trailing_whitespace = false
16+
17+
[*.vtc]
18+
indent_size = 4
19+
20+
[Makefile*]
21+
indent_style = tab
22+
23+
[*.{c,h}]
24+
indent_style = tab
25+
indent_size = 8

.github/workflows/ci.yml

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,58 @@ on:
66
pull_request:
77
branches: [main]
88

9+
env:
10+
CARGO_TERM_COLOR: always
11+
912
jobs:
10-
build:
13+
lint:
14+
name: Rust Lint
1115
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: dtolnay/rust-toolchain@stable
19+
with:
20+
targets: wasm32-unknown-unknown
21+
components: clippy, rustfmt
22+
23+
- name: Check formatting
24+
working-directory: examples
25+
run: cargo fmt --all --check
26+
27+
- name: Run clippy
28+
working-directory: examples
29+
run: cargo clippy --target wasm32-unknown-unknown --all-targets -- -D warnings
1230

31+
- name: Audit dependencies
32+
run: |
33+
cargo install cargo-audit --quiet
34+
cd examples && cargo audit
35+
36+
build-and-test:
37+
name: Build & Test
38+
runs-on: ubuntu-latest
1339
steps:
1440
- uses: actions/checkout@v4
1541

16-
- name: Build and test in Docker
42+
- name: Build Docker image
43+
run: docker build -t vmod-wasm-ci .
44+
45+
- name: Run tests
46+
run: docker run --rm vmod-wasm-ci make check
47+
48+
- name: Check binary sizes
1749
run: |
18-
docker build \
19-
--build-arg WASMTIME_VERSION=44.0.0 \
20-
-t vmod-wasm-test .
21-
docker run --rm vmod-wasm-test make check
50+
docker run --rm vmod-wasm-ci sh -c '
51+
MAX_SIZE=512000
52+
FAILED=0
53+
for f in /src/tests/wasm/*.wasm; do
54+
SIZE=$(stat -c%s "$f")
55+
NAME=$(basename "$f")
56+
echo "$NAME: $SIZE bytes"
57+
if [ $SIZE -gt $MAX_SIZE ]; then
58+
echo "ERROR: $NAME exceeds 500 KiB limit ($SIZE bytes)"
59+
FAILED=1
60+
fi
61+
done
62+
exit $FAILED
63+
'

CONTRIBUTING.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Contributing to vmod-wasm
2+
3+
Thank you for considering a contribution to vmod-wasm.
4+
5+
## Prerequisites
6+
7+
- Rust toolchain (stable) with the `wasm32-unknown-unknown` target
8+
- Docker (for running the full test suite)
9+
- Varnish 8.0+ development headers (for native builds)
10+
11+
Install the Rust target:
12+
13+
```shell
14+
rustup target add wasm32-unknown-unknown
15+
```
16+
17+
## Development Workflow
18+
19+
1. **Build Wasm modules:**
20+
21+
```shell
22+
make build
23+
```
24+
25+
2. **Run lints:**
26+
27+
```shell
28+
make lint
29+
```
30+
31+
3. **Run the full test suite (Docker):**
32+
33+
```shell
34+
make test
35+
```
36+
37+
4. **Format code:**
38+
39+
```shell
40+
make fmt
41+
```
42+
43+
## Writing a New Wasm Module
44+
45+
1. Create a new crate under `examples/`:
46+
47+
```shell
48+
cargo init --lib examples/my-module
49+
```
50+
51+
2. Add it to the workspace in `examples/Cargo.toml`:
52+
53+
```toml
54+
members = [
55+
# ... existing members
56+
"my-module",
57+
]
58+
```
59+
60+
3. Set the crate type to `cdylib` in your module's `Cargo.toml`:
61+
62+
```toml
63+
[lib]
64+
crate-type = ["cdylib"]
65+
```
66+
67+
4. Implement the Proxy-Wasm ABI (use the `proxy-wasm` SDK) or the raw vmod-wasm host functions.
68+
69+
5. Write a `.vtc` integration test under `tests/` — see existing tests for examples.
70+
71+
## Code Style
72+
73+
- Run `cargo fmt` before committing (enforced in CI).
74+
- All clippy warnings are treated as errors in CI.
75+
- Keep `.wasm` binaries under 500 KiB (release build).
76+
77+
## Commit Messages
78+
79+
Use conventional commits:
80+
81+
```
82+
feat(module): add rate limiting to edge-security-filter
83+
fix(transform): handle empty response headers
84+
docs: update ARCHITECTURE.md with new module
85+
test: add VTC for bot detection edge case
86+
```
87+
88+
## Pull Request Process
89+
90+
1. Create a feature branch from `main`.
91+
2. Ensure all CI checks pass (`make lint && make test`).
92+
3. Update relevant documentation if behavior changes.
93+
4. Request review from a maintainer.
94+
95+
## Reporting Issues
96+
97+
Open a GitHub issue with:
98+
99+
- Varnish version
100+
- Wasmtime version (from `configure.ac`)
101+
- Steps to reproduce
102+
- Expected vs actual behavior

Dockerfile

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM varnish:9.0.1
1+
FROM varnish:9.0.3
22

33
ARG WASMTIME_VERSION=44.0.0
44

@@ -40,24 +40,15 @@ WORKDIR /src
4040

4141
COPY . .
4242

43-
# Build the test Wasm module (raw ABI)
44-
RUN cd examples/rust && cargo build --release \
43+
# Build all Wasm example modules via workspace
44+
RUN cd examples \
45+
&& cargo build --release --target wasm32-unknown-unknown \
4546
&& mkdir -p /src/tests/wasm \
46-
&& cp target/wasm32-unknown-unknown/release/test_module.wasm /src/tests/wasm/
47-
48-
# Build the proxy-wasm SDK test module
49-
RUN cd examples/proxy-wasm-filter && cargo build --release \
50-
&& cp target/wasm32-unknown-unknown/release/proxy_wasm_filter.wasm /src/tests/wasm/
51-
52-
# Build passthrough filter module (for filter chain tests)
53-
RUN cd examples/passthrough \
54-
&& cargo build --target wasm32-unknown-unknown --release \
55-
&& cp target/wasm32-unknown-unknown/release/passthrough.wasm /src/tests/wasm/
56-
57-
# Build transform filter module (for filter chain tests)
58-
RUN cd examples/transform \
59-
&& cargo build --target wasm32-unknown-unknown --release \
60-
&& cp target/wasm32-unknown-unknown/release/transform.wasm /src/tests/wasm/
47+
&& cp target/wasm32-unknown-unknown/release/test_module.wasm /src/tests/wasm/ \
48+
&& cp target/wasm32-unknown-unknown/release/proxy_wasm_filter.wasm /src/tests/wasm/ \
49+
&& cp target/wasm32-unknown-unknown/release/passthrough.wasm /src/tests/wasm/ \
50+
&& cp target/wasm32-unknown-unknown/release/transform.wasm /src/tests/wasm/ \
51+
&& cp target/wasm32-unknown-unknown/release/edge_security_filter.wasm /src/tests/wasm/
6152

6253
# Build the VMOD
6354
RUN echo "3.1.0" > vmod_vcs_version.txt \

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ check-local:
2222
-Dwasm_passthrough="$(abs_top_srcdir)/tests/wasm/passthrough.wasm" \
2323
-Dwasm_transform="$(abs_top_srcdir)/tests/wasm/transform.wasm" \
2424
-Dsdk_module="$(abs_top_srcdir)/tests/wasm/proxy_wasm_filter.wasm" \
25+
-Dedge_filter="$(abs_top_srcdir)/tests/wasm/edge_security_filter.wasm" \
2526
$$t || exit 1; \
2627
done; \
2728
else \

README.md

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ A Varnish VMOD that executes WebAssembly modules for HTTP request processing at
44

55
[![License: CC BY-NC 4.0](https://img.shields.io/badge/license-CC%20BY--NC%204.0-lightgrey.svg)](LICENSE)
66
[![CI](https://github.com/RamazanKara/vmod-wasm/actions/workflows/ci.yml/badge.svg)](https://github.com/RamazanKara/vmod-wasm/actions)
7+
![Wasmtime](https://img.shields.io/badge/Wasmtime-v44.0.0-blue)
8+
![Varnish](https://img.shields.io/badge/Varnish-8.0%2B-purple)
9+
![Proxy-Wasm ABI](https://img.shields.io/badge/Proxy--Wasm%20ABI-v0.2.1-green)
10+
711

812
## Overview
913

@@ -134,7 +138,17 @@ impl HttpContext for MyFilter {
134138
impl Context for MyFilter {}
135139
```
136140

137-
See [`examples/`](examples/) for complete examples.
141+
See [`examples/`](examples/) for complete examples, including the
142+
[edge-security-filter](examples/edge-security-filter/) — a production-grade
143+
module demonstrating rate limiting, bot detection, HTTP callouts, and metrics.
144+
145+
## Getting Started
146+
147+
New to vmod-wasm? Start here:
148+
149+
1. [Development Guide](docs/DEVELOPMENT.md) — Write, build, test, and deploy your first Proxy-Wasm module
150+
2. [Configuration Reference](docs/CONFIGURATION.md) — All VCL functions and recommended settings
151+
3. [Architecture](docs/ARCHITECTURE.md) — How vmod-wasm works internally
138152

139153
## Building
140154

@@ -164,26 +178,48 @@ docker run --rm vmod-wasm-dev make check
164178
## Architecture
165179

166180
```
167-
VCL -> vmod_wasm.c -> wasm_engine.c -> Wasmtime -> .wasm module
168-
|
169-
host_functions.c (env + WASI)
170-
proxy_wasm.c (Proxy-Wasm ABI)
171-
proxy_wasm_http.c (HTTP callouts)
172-
store_pool.c (instance pooling)
173-
http_pool.c (connection pooling)
174-
vdp_wasm.c (response body streaming)
181+
┌────────────────┐
182+
│ VCL Config │
183+
└───────┬────────┘
184+
185+
┌────────────▼────────────┐
186+
│ vmod_wasm.c │
187+
│ (VCL function layer) │
188+
└────────────┬────────────┘
189+
190+
┌────────────────────┼───────────────────┐
191+
│ │ │
192+
┌─────────▼──────┐ ┌─────────▼────────┐ ┌──────▼────────┐
193+
│ wasm_engine.c │ │ proxy_wasm.c │ │ host_funcs.c │
194+
│ (Wasmtime) │ │ (ABI lifecycle) │ │ (env + WASI) │
195+
└─────────┬──────┘ └─────────┬────────┘ └───────────────┘
196+
│ │
197+
┌─────────▼──────┐ ┌─────────▼────────┐
198+
│ store_pool.c │ │ proxy_wasm_ │
199+
│ (instance pool)│ │ http/shared/ │
200+
└────────────────┘ │ headers/metrics │
201+
└─────────┬────────┘
202+
203+
┌────────────▼────────────┐
204+
│ http_pool.c │
205+
│ (connection pool + │
206+
│ circuit breaker) │
207+
└────────────────────────┘
175208
```
176209

177210
## Documentation
178211

212+
- [Architecture](docs/ARCHITECTURE.md) — Detailed component design and request lifecycle
213+
- [Development Guide](docs/DEVELOPMENT.md) — Writing your first Proxy-Wasm module
214+
- [Configuration Reference](docs/CONFIGURATION.md) — All VCL functions with parameters
179215
- [Proxy-Wasm Compatibility](docs/COMPATIBILITY.md) — ABI coverage matrix
180-
- [Security Model](docs/SECURITY.md)isolation, threat model, controls
181-
- [Production Guide](docs/PRODUCTION.md)deployment, monitoring, tuning
216+
- [Security Model](docs/SECURITY.md)Isolation, threat model, supply chain security
217+
- [Production Guide](docs/PRODUCTION.md)Deployment, hot-reload, monitoring, capacity planning
182218

183219
## License
184220

185221
CC BY-NC 4.0 — see [LICENSE](LICENSE).
186222

187223
## Contributing
188224

189-
Contributions welcome.
225+
Contributions welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

0 commit comments

Comments
 (0)