Header Presence Condition
The headers_present condition predicate gates a filter on whether headers are present, whatever their values
Versions marked “overview” do not contain this page. Selecting one opens that version’s documentation overview.
Category: Practical
Task: The headers_present condition predicate gates a filter on whether headers are present, whatever their values
Prerequisites: The product runtime and any backend services referenced by this configuration.
This configuration comes from the selected release. The example has not been run here; external services are not bundled.
Download the source file.
# Header Presence Condition
#
# The `headers_present` condition predicate gates a filter on whether
# headers are present, whatever their values. Every listed header must be
# there and names are case-insensitive, so `unless: {headers_present: [...]}`
# runs a filter only when the header is missing.
#
# Here it fills in defaults without overwriting anything: a request with
# no X-Tenant gets X-Tenant: public on its way to the backend, and a
# response with no Cache-Control gets Cache-Control: no-store on its way
# back. Values the client or the backend sent pass through untouched. The
# two defaults live in separate filters because a filter skipped by its
# request conditions also skips its response phase.
#
# Request headers come from the client, so any client can skip a filter
# gated by `unless: {headers_present: [...]}` just by sending the header.
# Only gate filters that way when that's fine, or when a trusted hop in
# front of the proxy sets or strips the header.
#
# Usage:
# cargo run -p praxis-proxy -- -c examples/configs/pipeline/header-presence-condition.yaml
#
# Exercise:
# curl -s -D- http://localhost:8080/
# # -> backend sees X-Tenant: public; response has Cache-Control: no-store
# curl -s -D- -H "X-Tenant: acme" http://localhost:8080/
# # -> backend sees X-Tenant: acme
listeners:
- name: default
address: "127.0.0.1:8080"
filter_chains:
- main
filter_chains:
- name: main
filters:
# Default the tenant only when the client didn't name one.
- filter: headers
conditions:
- unless:
headers_present: ["X-Tenant"]
request_set:
- name: "X-Tenant"
value: "public"
# Default Cache-Control only when the backend didn't set one.
- filter: headers
response_conditions:
- unless:
headers_present: ["Cache-Control"]
response_set:
- name: "Cache-Control"
value: "no-store"
- filter: router
routes:
- path_prefix: "/"
cluster: backend
- filter: load_balancer
clusters:
- name: backend
endpoints:
- "127.0.0.1:3000"
insecure_options:
allow_private_endpoints: true # example proxies to local backends