Force Case
The Force Case middleware enforces specific header casing for both incoming requests and outgoing responses.
HTTP headers are typically case-insensitive according to the RFC 7230 specification, but some legacy systems or APIs require headers to maintain specific capitalization patterns. This middleware ensures that designated headers preserve their exact case format instead of being normalized to canonical MIME header format.
How It Works
The Force Case middleware operates on both request and response headers:
Request Processing
When a request arrives, the middleware examines each configured header:
- Checks if the header exists in canonical MIME format (for example,
Xmlhttprequest
) - If found, renames it to the specified case format (for example,
XMLHttpRequest
) - Removes the canonical version to avoid duplicates
Response Processing
When the response is generated, the middleware performs the same operation:
- Examines response headers for canonical versions of configured headers
- Renames them to the specified case format
- Ensures the response maintains the required header casing
Configuration Example
- Force Case Middleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: force-case
namespace: apps
spec:
plugin:
forcecase:
headers:
- "SOAPAction"
- "XMLHttpRequest"
- "MyCompany-APIKey"
In this example, the middleware ensures that:
SOAPAction
stays asSOAPAction
(notSoapaction
)XMLHttpRequest
stays asXMLHttpRequest
(notXmlhttprequest
)MyCompany-APIKey
stays asMyCompany-APIKey
(notMycompany-Apikey
)
Configuration Options
Field | Description | Default | Required |
---|---|---|---|
headers | List of header names that should maintain their specific casing. Each header name must be specified exactly as it should appear in requests and responses. | Yes |
Testing and Validation
Testing the Force Case middleware requires careful consideration because most web services automatically convert headers to canonical MIME format, making it difficult to verify if the middleware is working correctly.
Recommended Testing Setup
Use header-preserving services to accurately validate the Force Case middleware:
- Echo Service for Request Headers
- IngressRoute
- HTTPBin for Response Headers
- IngressRoute
Using the mendhak/http-https-echo service with the PRESERVE_HEADER_CASE
environment variable set to true
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo
namespace: apps
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: mendhak/http-https-echo
env:
- name: PRESERVE_HEADER_CASE
value: "true"
---
apiVersion: v1
kind: Service
metadata:
name: echo
namespace: apps
spec:
ports:
- name: http
targetPort: 8080
port: 80
selector:
app: echo
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: echo-ingressroute
namespace: apps
spec:
entryPoints:
- web
routes:
- match: Host(`echo.docker.localhost`)
kind: Rule
services:
- name: echo
port: 80
passHostHeader: false
middlewares:
- name: force-case
Using the kennethreitz/httpbin service to test response headers through the /response-headers
endpoint.
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: apps
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: apps
spec:
ports:
- name: http
targetPort: 80
port: 80
selector:
app: httpbin
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: httpbin-ingressroute
namespace: apps
spec:
entryPoints:
- web
routes:
- match: Host(`httpbin.docker.localhost`)
kind: Rule
services:
- name: httpbin
port: 80
passHostHeader: false
middlewares:
- name: force-case
Testing Example
Request Header Test:
# Test request header casing with echo service
curl http://echo.docker.localhost -H "xMLHttpRequest: asd"
Expected Response:
{
"path": "/",
"headers": {
"Host": "10.42.0.53:8080",
"User-Agent": "curl/8.15.0",
"Accept": "*/*",
"XMLHttpRequest": "asd",
"X-Forwarded-For": "10.42.0.1",
"X-Forwarded-Host": "echo.docker.localhost"
}
}
Note how xMLHttpRequest
was converted to XMLHttpRequest
by the Force Case middleware.
What you'd see with standard services:
{
"headers": {
"Xmlhttprequest": "asd"
}
}
This canonical form appears even when the middleware works correctly, making validation impossible with standard services.
Important Considerations
-
Performance Impact: The middleware only processes headers that differ from their canonical MIME format. Headers that already match canonical format are not modified, minimizing processing overhead.
-
Header Validation: The middleware requires at least one header to be configured. Empty header lists will result in configuration validation errors.
-
Case Sensitivity: Header names in the configuration must match exactly how they should appear in the final request or response. The middleware does not perform any case conversion beyond the specified format.
-
Testing: Always use header-preserving services to accurately validate the Force Case middleware.