Forum Discussion

Daniel_Frye_222's avatar
Daniel_Frye_222
Icon for Nimbostratus rankNimbostratus
Jul 14, 2005

Rewrite host with an iRule?

Hello, hopefully someone knows the answer to this. I'm trying to find a way with an iRule (or any functionality really) to take a url like https://apple.fruit.com/application/xyz.html and convert it to

 

https://peanut.bean.com/application/xyz.html as it goes through the bigip (running v9) then pass it to the servers on the Bea Weblogic backend (doing all SSL encrypt/decrypt on the LB, backend just gets plain http). The catch is we cannot redirect the browser client to the peanut.bean.com site, the end user must always see apple.fruit.com. To make it even more complicated, sometimes the app will send back a payload with a URL inside it for the user that we need to change from peanut.bean.com to apple.fruit.com.

 

 

Is there a way to do this or are we just stuck?

 

 

Thanks for any help.

4 Replies

  • You aren't stuck. You can do something like the following:

    when HTTP_REQUEST {
       Don't allow data to be chunked so we can correctly
       replace payload below
      if { [HTTP::version] eq "1.1" } {
          if { [HTTP::header is_keepalive] } {
             HTTP::header replace "Connection" "Keep-Alive"
          }
          HTTP::version "1.0"
      }
       change host header
      if { [HTTP::host] eq "apple.fruit.com" } {
        HTTP::header replace "Host" "peanut.bean.com"
      }
    }
    when HTTP_RESPONSE {
        collect response data
       if { [HTTP::header exists "Content-Length"] } {
          set content_length [HTTP::header "Content-Length"]
       } else {
          set content_length 4294967295
       }
       if { $content_length > 0 } {
          HTTP::collect $content_length
       }
    }
    when HTTP_RESPONSE_DATA {
      set find "peanut.bean.com"
      set replace "apple.fruit.com"
      set offset 0
      set diff [expr [string length $replace] - [string length $find]]
       Get indices of all instances of find string in the payload
      set indices [regexp -all -inline -indices $find [HTTP::payload]]  
      foreach idx $indices {
        set start [expr [lindex $idx 0] + $offset]
        set end [expr [lindex $idx 1] + $offset]
        set len [expr {$end - $start + 1}]
         replace the instance of find with the contents of replace
        HTTP::payload replace $start $len $replace
         modify offset if the replace string is larger or smaller
         than find.
        incr offset $diff
      }
    }

    In the HTTP_REQUEST event, I've used the HTTP::header replace command to replace the host header. and in the HTTP_RESPONSE_DATA event, I've used a regexp call to return all start,end pairs of the peanut.bean.com string and replaced it with apple.fruit.com.

    Good luck!

    -Joe
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    I would like to add a note that Joe's example is a good complete example that shows how to abstract the find and replace strings into variables. In reality, you could save some performance in the iRule by replacing the diff variable with the actual literal difference value. For example, "peanut.bean.com" is 15 characters and "apple.fruit.com" is also 15 characters, so instead of calculating: [string length $replace] - [string length $find], simply remove the line for setting the diff variable and also replace the $diff with 0. This optimization logic could also be applied to the find and replace variables as well. Simply using the strings "peanut.bean.com" and "apple.fruit.com" instead of the variables will improve the performance of the iRule. Basically, the more literals you can use vs. evaluating commands, the better the performance will be.

     

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Oh, I also forgot to mention, that you may want to set a variable in the HTTP_REQUEST event when the host matches peanut.bean.com. This variable can then be used in the HTTP_RESPONSE event to trigger the actual collection of the response for the search and replace. This prevents the unnecessary buffering and searching of the response when the original host was not peanut.bean.com.

     

  • Thanks everyone for the info. I haven't had time to put everything into the LB yet but should be a piece of cake to do what we need. Thanks again.