Forum Discussion

gost2307_337235's avatar
gost2307_337235
Icon for Nimbostratus rankNimbostratus
Oct 24, 2017

Replace string using stream profile from backend server to client

We have the problem to rewrite string in Stream Profile (iRule). The client is requesting the URL: "https://abc.com"; and the backend server responded with absolute URL Hostname "def.com". Because of this response we are getting failure message, so we want F5 to replace this string from "abc.com" to "def.com". We tried some different iRules but we couldn't achieve it. Please help us to find the solution. The following iRule we are using right now.

'' when HTTP_REQUEST {
 Disable STREAM processing for request (ingress) traffic
STREAM::disable    

 Remove the Accept-Encoding header to disable server side compression
HTTP::header remove Accept-Encoding

 Replace the incoming Host header to match what the server expects
HTTP::header replace Host "defp.com"

}

when HTTP_RESPONSE {
if { [HTTP::header exists Location] } {
     If this is a redirect response, replace http://def.com with https://abc.com

    HTTP::header replace Location [string map {"http://def.com" "https://abc.com"} [HTTP::header Location]            
}

 Use a STREAM expression to remap all object references in the payload (HTML body) with the external host name
STREAM::expression {@http://def.com@https://abc.com@ }
STREAM::enable


}

3 Replies

  • Hi,

    you can try this irule. the stream commands are in variable to support disabling stream profile and manage only 30X redirects.

    rewriting try to convert absolute URL to relative URLs if the public URL is based on the service requested.

    when RULE_INIT {
        unset static::rewrite_table
        array set static::rewrite_table {
            "https://www.company.com"   "http://srv-internal.company.local"
            "https://www2.company.com"   "http://srv-internal2.company.local"
        }
        set static::rewrite_table_map [list]
        set static::rewrite_table_stream [list]
        foreach item [array names static::rewrite_table] {
            lappend static::rewrite_table_map $static::rewrite_table($item)/ $item/ $static::rewrite_table($item) $item/
            lappend static::rewrite_table_stream "@$static::rewrite_table($item)/@$item/@"
        }
        log local0. $static::rewrite_table_map
        log local0. $static::rewrite_table_stream
         create stream commands in variables to run them only id stream profile is enabled
        set static::stream_disable "STREAM::disable"
        set static::stream_enable "STREAM::enable"
         change stream expression to convert current site response to relative URI.
        set static::stream_expression "STREAM::expression \[string map \"\$req_proto://\$req_host/ /\" \$static::rewrite_table_stream\]"
    }
    
    when CLIENT_ACCEPTED {
         set default protocol to http. change it to https if clientssl profile is assigned to the VS.
        if { [PROFILE::exists clientssl] == 1} {
            set req_proto "https"
        } else {
            set req_proto "http"
        }
        set stream_profile_enabled [PROFILE::exists stream]
    }
    
    when HTTP_REQUEST {
         Capture request hostname
        set req_host [HTTP::host]
        if {$stream_profile_enabled} {
             Disable the stream filter for all requests
            eval $static::stream_disable
    
             LTM does not uncompress response content, so if the webserver has compression enabled
             we must prevent the server from send us a compressed response by changing the request
             header that indicates client support for compression (on our LTM client-side we can re-
             apply compression before the response goes across the Internet)
            HTTP::header remove "Accept-Encoding"
        }
    }
    
    when HTTP_RESPONSE {
        if { [HTTP::status]  matches "30?"} {
             This is a 302 redirect with a absolute Location URI
            HTTP::header replace Location [string map [string map "$req_proto://$req_host/ /" $static::rewrite_table_map] [HTTP::header Location]]
        } elseif {[HTTP::header value Content-Type] starts_with "text"} {
             Apply stream expression stored in RULE_INIT event
            if {$stream_profile_enabled} {
                eval $static::stream_expression
    
                 Enable the stream filter for this response only
                eval $static::stream_enable
            }
        }
    }
    
  • Did you try using an HTTP policy ? After you created you can create a RULE (not I-rule) where you rewrite URL. I tried it and i find it easier than i-rule development