Skip to content

Traefik plugin for mapping existing headers into new headers

License

Notifications You must be signed in to change notification settings

DocPlanner/header-map

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Header Map

A Traefik middleware plugin that derives new request headers from existing ones using regex pattern matching. It replicates the behavior of the nginx map directive.

Overview

Header Map inspects one or more incoming request headers (e.g. Host, User-Agent), matches their values against a list of regex rules, and sets new headers with the corresponding values. If no rule matches, a configurable default value is used.

All mapping rules are defined in Traefik's dynamic configuration (Middleware CRD in Kubernetes, file provider, Docker labels, etc.), so adding or removing rules requires no plugin rebuild and no Traefik restart.

Configuration

Static (plugin registration)

# traefik.yml
experimental:
  plugins:
    header-map:
      moduleName: github.com/rodrigoechaide/header-map
      version: v0.1.0

Dynamic (middleware definition)

File provider

# dynamic.yaml
http:
  middlewares:
    header-map:
      plugin:
        header-map:
          mappings:
            - sourceHeader: "Host"
              targetHeader: "X-APP-ID"
              defaultValue: "unknown_locale"
              rules:
                - regex: 'example\.com$'
                  value: "en"
                - regex: 'example\.es$'
                  value: "es"
            - sourceHeader: "User-Agent"
              targetHeader: "X-UA-Device"
              defaultValue: "desktop"
              rules:
                - regex: "(?i)(android|iphone|mobile)"
                  value: "mobile"

  routers:
    my-router:
      rule: "PathPrefix(`/`)"
      service: my-service
      middlewares:
        - header-map

Kubernetes CRD

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: header-map
  namespace: traefik-system
spec:
  plugin:
    header-map:
      mappings:
        - sourceHeader: "Host"
          targetHeader: "X-APP-ID"
          defaultValue: "unknown_locale"
          rules:
            - regex: 'example\.com$'
              value: "en"
            - regex: 'example\.es$'
              value: "es"
        - sourceHeader: "User-Agent"
          targetHeader: "X-UA-Device"
          defaultValue: "desktop"
          rules:
            - regex: "(?i)(android|iphone|mobile)"
              value: "mobile"

Configuration Reference

Field Type Required Description
mappings []Mapping Yes List of header mapping definitions

Mapping:

Field Type Required Description
sourceHeader string Yes Request header to read (e.g. Host, User-Agent)
targetHeader string Yes Request header to set with the matched value
defaultValue string No Value to use when no rule matches. If empty, no header is set on miss.
rules []Rule No Ordered list of regex rules. First match wins.

Rule:

Field Type Required Description
regex string Yes Go-flavored regular expression to match against the source header value
value string Yes Value to set in the target header when the regex matches

Behavior

  • For each mapping, the source header value is tested against rules in order. The first matching regex wins.
  • If sourceHeader is Host and the header is absent from the request, the plugin falls back to req.Host.
  • Regex patterns use Go's regexp syntax (RE2). Use (?i) for case-insensitive matching.
  • Regex patterns are compiled once when the middleware is initialized, not on every request.

Local Development

Clone the repository and use the provided Makefile:

make test    # run unit tests with coverage
make lint    # run golangci-lint (requires golangci-lint installed)

Testing with Docker Compose

A ready-to-use local development setup is included in the docker/ directory. It loads the plugin from the repo root using Traefik's local plugin mode.

docker/
├── docker-compose.yml          # Traefik + whoami backend
└── traefik-config/
    ├── traefik.yml             # Traefik static config (local plugin registration)
    └── dynamic.yml             # Dynamic config (middleware rules + routing)

Start the stack:

cd docker
docker compose up

Test the plugin:

# Host mapping: localhost -> "local-test"
curl -s http://localhost/ | grep X-App-Id

# Host mapping: example1.pl -> "pl"
curl -s -H "Host: example1.pl" http://localhost/ | grep X-App-Id

# User-Agent mapping: mobile device -> "mobile"
curl -s -H "User-Agent: Mozilla/5.0 (iPhone)" http://localhost/ | grep X-Ua-Device

The Traefik dashboard is available at http://localhost:8080.

Edit local/traefik-config/dynamic.yml to change mapping rules. Edit headermap.go at the repo root to change plugin logic, then restart the stack with docker compose restart traefik.

Publishing to the Traefik Plugin Catalog

To make the plugin available in the Traefik Plugins Catalog:

  1. Ensure the GitHub repository is public.
  2. Add the traefik-plugin topic to the repository.
  3. Verify .traefik.yml exists at the repo root with valid testData.
  4. Verify go.mod exists at the repo root.
  5. Create a git tag (e.g. v0.1.0).
  6. The catalog polls GitHub daily and will pick up the plugin automatically.

License

Apache 2.0

About

Traefik plugin for mapping existing headers into new headers

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors