Forum Discussion
LTM Policy for HTTP Host rewrite
Hi jomedusa ,
LTM Policies are preferred when it meets all the criteria, but there are some limitations that require an iRule. In this case you might need to leverage a stream profile + iRule to handle the Swagger CORS issue. You can opt for hybird LTM Policy + Irule but I don't like to mix these deployments as it created admin overheard and complexity. BTW check out our BIG-IP iRules Assistant Irules Assistant, this is what I used to help create and validate the iRule.
You will need a HTTP, Stream, profile ( keep the src/target empty. If your using a compression profile be aware that stream operations dont work on gzip HTTP bodies.
when HTTP_REQUEST {
# Preserve what the client asked for
set client_host [HTTP::host]
# Rewrite Host header to what backend expects
HTTP::header replace Host "backend.internal.example.com"
# Disable compression so STREAM can inspect the body
HTTP::header remove "Accept-Encoding"
# Default off; enable selectively on response
STREAM::disable
}
when HTTP_RESPONSE {
# Fix CORS allow-origin if backend echoes its own hostname/scheme
if { [HTTP::header exists "Access-Control-Allow-Origin"] } {
HTTP::header replace "Access-Control-Allow-Origin" "https://$client_host"
}
# Fix Location header on 3xx (or use HTTP profile Redirect Rewrite = Matching)
if { [HTTP::header exists "Location"] } {
HTTP::header replace Location \
[string map "backend.internal.example.com $client_host" [HTTP::header Location]]
}
# Body rewrite: swagger.json, HTML, JS that reference the internal host
switch -glob -- [string tolower [HTTP::header "Content-Type"]] {
"application/json*" -
"application/*+json*" -
"text/html*" -
"text/javascript*" -
"application/javascript*" {
STREAM::expression "@backend.internal.example.com@$client_host@"
STREAM::enable
}
}
}
Here is what our AI Assistant calculated from the iRule above:
- Objective
• Preserve the client’s original Host header for later use.
• Rewrite the Host header to the internal backend hostname so the server sees what it expects.
• Disable compression on the request so that the response body can be inspected and rewritten.
• On the response, restore CORS and redirect headers to the client’s host and rewrite in-body references to match the original host. - Execution Flow
• HTTP_REQUEST
– set client_host to the value of the incoming Host header (HTTP::host).
– replace the Host header with “backend.internal.example.com” (HTTP::header replace Host).
– remove the Accept-Encoding header to disable compression (HTTP::header remove "Accept-Encoding").
– disable the stream filter by default (STREAM::disable).
- HTTP_RESPONSE
– if “Access-Control-Allow-Origin” exists, replace its value with “https://” (HTTP::header replace).
– if “Location” exists, map any “backend.internal.example.com” in its value back to the original client_host (string map+HTTP::header replace).
– inspect the Content-Type header; for JSON, HTML, or JavaScript types, set up a stream expression to rewrite in-body “backend.internal.example.com” to client_host (STREAM::expression) and enable the stream filter (STREAM::enable).
Summary
This iRule fronts an internal backend by swapping the Host header on requests and then, on the way back, transparently restoring client-facing host references in CORS, redirects, and body content for supported MIME types.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com