Redirecting HTTP to HTTPS is a small change that can have large application effects. An incorrect hostname, missing query string or redirect loop can make an otherwise healthy service unusable.
A correct implementation starts with three decisions: which requests may be redirected, the exact destination and the status code that matches the clients using the service.
Use a controlled destination
Building a redirect directly from an unchecked Host header makes the destination depend on client input. For a single public application, a fixed canonical hostname is often easier to reason about.
This example is intended for a port-80 HTTP virtual server with an HTTP profile. Its port-443 HTTPS service must be configured separately.
when HTTP_REQUEST {
if { [HTTP::has_responded] } {
return
}
set request_host [string tolower [HTTP::host]]
switch -- $request_host {
"portal.example.nl" -
"portal.example.nl:80" {
HTTP::respond 302 noserver \
Location "https://portal.example.nl[HTTP::uri]"
return
}
default {
HTTP::respond 400 \
content "Unknown host" noserver
return
}
}
}
The destination hostname is fixed, while the request URI is retained. A request for /account?view=profile therefore keeps its path and query string under HTTPS.
HTTP::has_responded was introduced in BIG-IP 14.0. Verify command availability on older releases. See the command reference.
Understand response generation
HTTP::redirect sends a 302 response. HTTP::respond can generate a chosen status code with a Location header. Once a response has been generated, other logic must not try to generate or modify another response for the same request. F5 describes these behaviours in the redirect and respond references.
This matters when several iRules or policies are attached to the virtual server. A return ends the current execution; it is not a global instruction stopping all other attached logic. Identify every component capable of generating a response and make their interaction explicit.
Choose the status code deliberately
For validation, a temporary redirect can be easier to change than a permanent one. API requests introduce another consideration: preserving the request method and body.
| Status | Meaning | Method behaviour |
|---|---|---|
| 301 | Permanent | A client may change POST to GET |
| 302 | Temporary | A client may change POST to GET |
| 307 | Temporary | Method and request body are preserved |
| 308 | Permanent | Method and request body are preserved |
These distinctions are defined by HTTP Semantics, RFC 9110. The appropriate choice depends on the client and application, rather than a general preference for permanent redirects.
For an API, configuring clients to use HTTPS directly may be preferable to making normal operation depend on redirects.
Investigate loops across the proxy chain
A loop can occur when BIG-IP terminates TLS but forwards HTTP to a backend that insists on HTTPS. The browser already uses HTTPS, while the backend repeatedly sees an unencrypted connection and returns the same public HTTPS destination.
Investigate the agreement between proxy and application about the original protocol. Which forwarding headers are trusted? Where are they set or replaced? Can client-supplied values be mistaken for trusted proxy information?
The correction must match that trust boundary. Adding a header without understanding how the application interprets it can exchange a redirect problem for a security problem.
Test paths, queries and clients
Do not limit verification to the homepage. Test representative paths, query strings, unknown hostnames and relevant request methods.
curl --resolve portal.example.nl:80:192.0.2.10 \
--silent --show-error \
--dump-header - \
--output /dev/null \
'http://portal.example.nl/account?view=profile'
Inspect the status and complete Location header. Test the HTTPS destination independently and check whether it redirects again. For an API, include the actual client's handling of the selected redirect code in acceptance testing.
A Local Traffic Policy may also suit a simple redirect; an iRule becomes useful when additional conditions or custom behaviour are required. F5 covers both approaches in its Policies and iRules training.
The implementation is complete when the destination is controlled, URI handling is correct and the application behaves as expected across the full proxy chain.