While best practices for virtualized web applications may indicate that relative self-referencing links and redirects (those which don't include the protocol or the hostname) are preferable to absolute ones (those which do), many applications load balanced by our gear still send absolute self-references. This drives a fairly common requirement when proxying or virtualizing HTTP applications: To manipulate any redirects the servers may set such that they fully support the intended proxy or virtualization scheme. In some cases the requirement is as simple as changing "http://" to "https://" in every redirect the server sends because it is unaware of SSL offloading. Other applications or environments may require modifications to the host, URI, or other headers. LTM provides a couple of different ways to manage server-set redirects appropriately.

HTTP profile option: "Rewrite Redirects"

The LTM http profile contains the "Rewrite Redirects" option which supports rewriting server-set redirects to the https protocol with a hostname matching the one requested by the client. The possible settings for the option are "All", "Matching", Node", and "None".


Rewrite Redirects settings for http profile
Setting Effect Resulting Redirect Use Case
All Rewrites all HTTP 301, 302, 303, 305, or 307 redirects https://<requested_hostname>/<requested_uri> Use "All" if all redirects are self-referencing and the applicaiton is intended to be secure throughout.  You should also use "All" if your application is intended to be secure throughout, even if redirected to another hostname.
Matching Rewrites redirects when the request and the redirect are identical except for a trailing slash. See SOL6912 https://<requested_hostname>/<requested_uri>/ Use "Matching" to rewrite only courtesy redirects intended to append a missing trailing slash to a directory request.
Node Rewrites all redirects containing pool member IP addresses instead of FQDN https://<vs_address>/<requested_uri> Use "Node" If your servers send redirects that include the server's own IP address instead of a hostname.
None No redirects are rewritten   Default setting

Note that all options will rewrite the specified redirects to HTTPS, so there must be an HTTPS virtual enabled on the same address as the HTTP virtual server.

iRule Options

While these options cover a broad range of applications, they may not be granular enough to meet your needs. For example, you might only want to re-write the hostname, not the protocol, to support HTTP-only proxying scenarios. You might need it to temporarily work around product issues such as those noted in SOL8535/CR89873. In these cases, you can use an iRule that uses the HTTP::is_redirect command to identify server-set redirects and selectively rewrite any part of the Location header using the HTTP::header command with the "replace" option.

Here's an iRule that rewrites just one specific hostname to another, preserving the protocol scheme and URI as set by the server:

  if { [HTTP::is_redirect] }{
    HTTP::header replace Location [string map {"A.internal.com" "X.external.com"} [HTTP::header Location]]

Here's one that rewrites both relative and absolute redirects to absolute HTTPS redirects, inserting the requested hostname when re-writing the relative redirect to absolute:

  # save hostname for use in response
  set fqdn_name [HTTP::host]
  if { [HTTP::is_redirect] }{
    if { [HTTP::header Location] starts_with "/" }{
      HTTP::header replace Location "https://$fqdn_name[HTTP::header Location]"
    } else {
      HTTP::header replace Location "[string map {"http://" "https://"} [HTTP::header Location]]"

The string map example could quite easily be adjusted or extended to meet just about any redirect rewriting need you might encounter. (The string map command will accept multiple replacement pairs which can come in handy if multiple hostnames or directory strings need to be re-written -- in many cases you can perform the intended replacements with a single string map command.)

Taking it a step further

As I mentioned earlier, redirects are only one place server self-references may be found. If absolute self-referencing links are embedded in the HTTP payload, you may need to build and apply a stream profile to perform the appropriate replacements. An iRule could also be used for more complex payload replacements if necessary. For the ultimate in redirect rewriting and all other things HTTP proxy, I direct your attention to the legendary ProxyPass iRule contributed to the DevCentral codeshare by Kirk Bauer (thanks, Kirk, for a very comprehensive & instructive example!)