add reverse_proxy, log, and abort tests

This commit is contained in:
Mohammed Al Sahaf 2026-06-06 22:32:45 +03:00
parent 2bc3a8e304
commit 75bd83677e
No known key found for this signature in database
3 changed files with 561 additions and 0 deletions

View file

@ -0,0 +1,102 @@
# Configure Caddy with abort directive
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
abort
respond "This should not be reached"
}
```
# NOTE: bare `abort` aborts the request without sending a response, so the
# client sees a transport-level connection close. We cannot assert this in
# Hurl (it errors on the broken HTTP exchange). The Caddyfile above is
# accepted and provisioned successfully, which the /load probe confirms.
# Configure Caddy with conditional abort
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
@blocked path /blocked*
abort @blocked
respond "OK"
}
```
# abort only affects matching paths
GET https://localhost:9443/allowed
[Options]
insecure: true
HTTP 200
[Asserts]
body == "OK"
# Configure Caddy with abort in route
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
route /api/* {
@invalid header X-API-Key ""
abort @invalid
respond "API OK"
}
respond "Not API"
}
```
# abort in route for matching condition
GET https://localhost:9443/other
[Options]
insecure: true
HTTP 200
[Asserts]
body == "Not API"
# Configure Caddy with abort after headers
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
@crawler header User-Agent *bot*
abort @crawler
respond "Normal user"
}
```
# abort based on User-Agent header
GET https://localhost:9443
User-Agent: Mozilla/5.0
[Options]
insecure: true
HTTP 200
[Asserts]
body == "Normal user"

View file

@ -0,0 +1,250 @@
# Each block routes Caddy's access log to a unique file under
# /tmp/caddy-log-spec/ and exposes that directory via a sidecar
# `file_server` site on :9081, so a subsequent GET can read the log
# back and assert the directive actually did what it claims.
#
# `roll_disabled` keeps the writer as a plain os.File so writes are
# visible to the next read without lumberjack rotation games.
#
# Files persist between runs; if you change a config block locally you
# may want to `rm -rf /tmp/caddy-log-spec` before re-running. CI runners
# start with a clean /tmp.
# Configure Caddy with the log directive writing to a real file
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
log {
output file /tmp/caddy-log-spec/basic.log {
roll_disabled
}
format json
}
respond "Logged response"
}
:9081 {
root * /tmp/caddy-log-spec
file_server
}
```
# Generate a logged request
GET https://localhost:9443/from-basic
[Options]
insecure: true
HTTP 200
[Asserts]
body == "Logged response"
# The log file exists and contains a JSON entry for the request above
GET http://localhost:9081/basic.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/from-basic\""
body contains "\"status\":200"
# Configure Caddy with log_skip
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
log {
output file /tmp/caddy-log-spec/skip.log {
roll_disabled
}
format json
}
log_skip /health
respond "OK"
}
:9081 {
root * /tmp/caddy-log-spec
file_server
}
```
# Requests we want logged and requests we want skipped
GET https://localhost:9443/skip-api
[Options]
insecure: true
HTTP 200
GET https://localhost:9443/health
[Options]
insecure: true
HTTP 200
# Logged path appears, skipped path does not
GET http://localhost:9081/skip.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/skip-api\""
body not contains "\"uri\":\"/health\""
# Configure Caddy with log_append
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
log {
output file /tmp/caddy-log-spec/append.log {
roll_disabled
}
format json
}
log_append user_id {http.request.header.X-User-Id}
log_append request_type "api"
respond "OK"
}
:9081 {
root * /tmp/caddy-log-spec
file_server
}
```
# Request that should produce a log entry with the appended fields
GET https://localhost:9443/append-target
X-User-Id: user123
[Options]
insecure: true
HTTP 200
# Both appended fields are present in the JSON log entry
GET http://localhost:9081/append.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/append-target\""
body contains "\"user_id\":\"user123\""
body contains "\"request_type\":\"api\""
# Configure Caddy with log_name routing requests to different loggers
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
log api_log {
output file /tmp/caddy-log-spec/name_api.log {
roll_disabled
}
format json
}
log static_log {
output file /tmp/caddy-log-spec/name_static.log {
roll_disabled
}
format json
}
log_name /api/* api_log
log_name /static/* static_log
respond "OK"
}
:9081 {
root * /tmp/caddy-log-spec
file_server
}
```
# Drive requests into each logger
GET https://localhost:9443/api/probe
[Options]
insecure: true
HTTP 200
GET https://localhost:9443/static/style.css
[Options]
insecure: true
HTTP 200
# api_log only contains /api entries
GET http://localhost:9081/name_api.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/api/probe\""
body not contains "\"uri\":\"/static/style.css\""
# static_log only contains /static entries
GET http://localhost:9081/name_static.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/static/style.css\""
body not contains "\"uri\":\"/api/probe\""
# Configure Caddy with log_skip driven by a named matcher
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
log {
output file /tmp/caddy-log-spec/named_matcher.log {
roll_disabled
}
format json
}
@health path /healthz /ready
log_skip @health
respond "OK"
}
:9081 {
root * /tmp/caddy-log-spec
file_server
}
```
# One logged path and two skipped paths
GET https://localhost:9443/named-api
[Options]
insecure: true
HTTP 200
GET https://localhost:9443/healthz
[Options]
insecure: true
HTTP 200
GET https://localhost:9443/ready
[Options]
insecure: true
HTTP 200
# Only the non-skipped path is present
GET http://localhost:9081/named_matcher.log
HTTP 200
[Asserts]
body contains "\"uri\":\"/named-api\""
body not contains "\"uri\":\"/healthz\""
body not contains "\"uri\":\"/ready\""

View file

@ -0,0 +1,209 @@
# Configure Caddy with reverse_proxy to echo server
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
reverse_proxy localhost:8080
}
http://localhost:8080 {
respond "Backend response: {method} {uri}"
}
```
# reverse_proxy forwards requests to upstream
GET https://localhost:9443/test
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "Backend response: GET /test"
# reverse_proxy preserves query parameters
GET https://localhost:9443/api?param=value
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "Backend response: GET /api?param=value"
# reverse_proxy handles POST requests
POST https://localhost:9443/submit
[Options]
delay: 500ms
insecure: true
```
{"data": "test"}
```
HTTP 200
[Asserts]
body == "Backend response: POST /submit"
# Configure Caddy with reverse_proxy and header manipulation
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
reverse_proxy localhost:8080 {
header_up X-Custom-Header "CustomValue"
header_down -Server
}
}
http://localhost:8080 {
respond "{header.X-Custom-Header}"
}
```
# reverse_proxy adds upstream headers
GET https://localhost:9443
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "CustomValue"
# Configure Caddy with reverse_proxy path rewriting
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
handle_path /api/* {
reverse_proxy localhost:8080
}
}
http://localhost:8080 {
respond "Backend: {uri}"
}
```
# reverse_proxy with handle_path strips prefix
GET https://localhost:9443/api/v1/users
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "Backend: /v1/users"
# Configure Caddy with reverse_proxy to multiple upstreams
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
reverse_proxy localhost:8080 localhost:8081
}
http://localhost:8080 {
respond "Backend 1"
}
http://localhost:8081 {
respond "Backend 2"
}
```
# reverse_proxy load balances between upstreams
GET https://localhost:9443
[Options]
delay: 500ms
insecure: true
HTTP 200
# Multiple requests may hit different backends
GET https://localhost:9443
[Options]
delay: 500ms
insecure: true
HTTP 200
# Configure Caddy with reverse_proxy and transport options
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
reverse_proxy localhost:8080 {
transport http {
dial_timeout 2s
}
}
}
http://localhost:8080 {
respond "OK"
}
```
# reverse_proxy respects transport settings
GET https://localhost:9443
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "OK"
# Configure Caddy with reverse_proxy and flush_interval
POST http://localhost:2019/load
Content-Type: text/caddyfile
```
{
skip_install_trust
http_port 9080
https_port 9443
local_certs
}
localhost {
reverse_proxy localhost:8080 {
flush_interval -1
}
}
http://localhost:8080 {
respond "Streaming response"
}
```
# reverse_proxy handles streaming with flush_interval
GET https://localhost:9443
[Options]
delay: 500ms
insecure: true
HTTP 200
[Asserts]
body == "Streaming response"