Uri version mapping

Problem this snippet solves:

This rule implements a stripped down set of functionality of the ProxyPass rule Kirk Bauer wrote. The requirements are to insert the application's version string in the URI before requests are sent to the application and to remove references to the version in the response content and headers.

The application expects a base string and full version string to be in the URI, but clients will only refer to the application using the base string. For example:

Client requests: www.example.com/my_app/login.php

The application expects: www.example.com/my_app/v1.0/login.php

On responses, a stream profile and STREAM::comands are used to remove references to the version string in the response content. We also remove the version string from the Location header in 30x redirects.

There are a few configuration requirements:

  1. A default pool on the virtual server

  2. An HTTP profile with Response Chunking set to Rechunk associated with the virtual server

  3. An empty stream profile associated with the virtual server

Code :

# insert_version_in_uri_rule
# v1.2 - Aaron Hooley @ LODOGA Security Limited
#
# This rule inserts a version string into the URI if it isn't already present.  It also removes the version string in response data and the Location header, if present.
#
# Configuration requirements:
#
# 1. To perform the response data replacement, the default, unconfigured stream profile must be configured on the virtual server
#
# 2. To force BIG-IP to recalculate the response content length for the stream replacement, a new HTTP profile must be added to the virtual server.
#    Response Chunking must be set to Rechunk on the custom HTTP profile

when RULE_INIT {
   # Current version number in format xx_yyy where x is the revision number and y is the version number
   set ::version_string "v12_002"

   # The base of the URI
   set ::uri_base "/my_app/"
   
   # Enable/disable debug logging to /var/log/ltm
   set ::uri_mapping_debug 1
}

when HTTP_REQUEST {
   # Log the original path if debug is enabled
   if {$::uri_mapping_debug}{log local0. "Original path: [HTTP::path]"}
   
   # If the path doesn't already start with the base URI and version, insert it
   if {not ([string tolower [HTTP::path]] starts_with "$::uri_base$::version_string")}{
      HTTP::path [string map [list $::uri_base "$::uri_base$::version_string/"] [HTTP::path]]
   
      # Log the modified path if debug is enabled
      if {$::uri_mapping_debug}{log local0. "Modified path: [string map [list $::uri_base "$::uri_base$::version_string/"] [HTTP::path]]"}
   }
}
when HTTP_RESPONSE {

   # Check if response is text
   if {[HTTP::header value "Content-Type"] starts_with "text"}{
      # Look in the response data for the string "/my_app/v12_002/" and replace it with "/my_app/"
      STREAM::expression @$::uri_base$::version_string/@$::uri_base@
      STREAM::enable
   }

   # Remove the version string from the HTTP Location header value in redirects
   if {[HTTP::is_redirect]}{
      HTTP::header value Location [string map [list $::uri_base "$::uri_base$::version_string/"] [HTTP::header value Location]]

      # Log the modified path if debug is enabled
      if {$::uri_mapping_debug}{log local0. "Modified Location header: [string map [list $::uri_base "$::uri_base$::version_string/"] [HTTP::header value Location]]"}
   }
}
Published Mar 18, 2015
Version 1.0

Was this article helpful?

1 Comment

  • Hi Master Hoolio,

     

    Could you please help me write the irule to append a string to existing URI? Below are the details. Can it be just a rewrite and not redirect?

     

    Original URL sent by user: online.abc.com/ova/login.jsp traffic sent to backend server should be: online.abc.com/online/ova/login.jsp

     

    Thanks in advance for the help!