Forum Discussion

John_Ogle_45372's avatar
John_Ogle_45372
Icon for Nimbostratus rankNimbostratus
Jan 25, 2010

URL rewrite (multiple)

 

I have three virtuals (SAP implmenetation) that need URL rewriting both ways. The client hits app1.company.com/index.html. When it gets passed to a pool member (server), the host field needs to be rewritten to read "server1.company.com". On the responses,the reverse needs to happen. My two questions are:

 

 

1) Does the following irule look sufficient?

 

2) Is there a better way to do this? Data group? etc.????

 

 

Thank you,

 

 

when HTTP_REQUEST {

 

if { ( [HTTP::host] equals "app1.company.com" ) } {

 

HTTP::header replace Host "server1.hostname.company.com"

 

}

 

if { ( [HTTP::host] equals "app2.company.com" ) } {

 

HTTP::header replace Host "server2.hostname.company.com"

 

}

 

if { ( [HTTP::host] equals "app3.company.com" ) } {

 

HTTP::header replace Host "server3.hostname.company.com"

 

}

 

}

 

when HTTP_RESPONSE {

 

if { ( [HTTP::host] equals "server1.hostname.company.com" ) } {

 

HTTP::header replace Host "app1.company.com"

 

}

 

if { ( [HTTP::host] equals "server2.hostname.company.com" ) } {

 

HTTP::header replace Host "app2.company.com"

 

}

 

if { ( [HTTP::host] equals "server3.hostname.company.com" ) } {

 

HTTP::header replace Host "app3.company.com"

 

}

 

}

 

3 Replies

  • There isn't a host header in responses. If the app uses fully qualified references to itself in response headers (like the Location header in redirects) or in response content (links, forms, etc), you'd need to use a stream profile and iRule to rewrite them.

    The proxypass and proxypassv10 iRules (Click here) would allow you to do this type of rewriting. Or for a smaller version, you can try something like the rule below. You'll need to add a blank stream profile to the iRule.

    For troubleshooting the rule, you can check the examples on the STREAM::expression wiki page (Click here).

     
     when HTTP_REQUEST { 
      
         Check the host header value (set to lowercase) 
        switch [string tolower [HTTP::host]] { 
           "app1.company.com" { 
               Replace the Host header 
      HTTP::header replace Host "server1.hostname.company.com" 
      
       Save the find/replace strings for responses 
      set internal_host "server1.hostname.company.com" 
      set external_host "app1.company.com" 
           } 
           "app2.company.com" { 
               Replace the Host header 
      HTTP::header replace Host "server2.hostname.company.com" 
      
       Save the find/replace strings for responses 
      set internal_host "server2.hostname.company.com" 
      set external_host "app2.company.com" 
           } 
           default { 
               Take some action for non-matching hosts? 
       In this example we do nothing to responses if there wasn't a match 
      set internal_host "" 
           } 
        } 
         If we're potentially going to rewrite the response headers and/or content 
         prevent the server from sending a compressed response 
        if {$internal_host ne "" && [HTTP::header exists "Accept-Encoding"]}{ 
      
            HTTP::header remove Accept-Encoding 
        } 
     } 
     when HTTP_RESPONSE { 
      
         Disable the stream filter by default 
        STREAM::disable 
      
         Check if we're potentially rewriting this response 
        if {$internal_host ne ""}{ 
      
            Rewrite the Location header for redirects 
           if {[HTTP::is_redirect]}{ 
      
              if {[HTTP::header Location] contains "$internal_hostname"}{ 
                 HTTP::header replace Location [string map "$internal_hostname $external_hostname" [HTTP::header Location]] 
      } 
           } 
            Rewrite the response content using a stream profile if it is text 
           if {[HTTP::header Content-Type] contains "text"}{ 
      
               Set the stream expression with the find/replace strings 
              STREAM::expression "@$internal_hostname@$external_hostname@" 
      
               Enable the stream filter 
              STREAM::enable 
           } 
        } 
     } 
     

    Aaron
  • Thank you very much for the input. Two questions.

     

     

    1) I was already going to use the iRule in conjunction with a STREAM profile to catch dynamically generated links in the payload. In your use of a stream profile in the iRule, is why are you temporarily disabling a stream profile and then enabling again at the end? Can you elaborate a bit? I do know that with a stream and http profile both applied to a virtual that the stream profile won't touch the headers which is why I'm asking.

     

     

    2) I am getting a syntax error on line 50 when I add it to the LTM

     

    {syntax error in expression "[HTTP::header Content-Type] contains "text")": extra tokens

     

     

    Thanks,

     

  • 1. With no iRule to configure the stream profile, when you add a stream profile to a VIP the filter is applied to both requests and responses regardless of the content type. I imagine there is unnecessary overhead in doing this when you only want to apply it to text responses. Also, with an iRule that calls STREAM::enable, the stream filter is left enabled for the life of the TCP connection or until STREAM::disable is called. So the idea of selectively enabling the stream filter in an iRule is to ensure the it's only enabled for text responses.

     

     

    2. The ) in that line was a typo. I corrected that in the post above.

     

     

    Aaron