# 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
