Forum Discussion

dihris_116090's avatar
dihris_116090
Icon for Nimbostratus rankNimbostratus
May 28, 2016
Solved

HTTP Rewrite header + pool based on URI

Hi,

I need to forward traffic from external URL to one of our internal servers based on URI. That has to be transparent for the browser with no redirect messages 3xx.

Searching in the forum and using codes from other members I constructed the following iRule though based on by debug it looks like I'm getting in problems with the HTTP response header.

I'm trying to modify the header for requests coming to externalsite.com/foobar --> internalsite.com/foobar and direct these requests to specific pool named "internal_pool" The reply back should contain the original header and all that has to be done transparent to the browser.

I would very much appreciate if any one can share an idea where I'm going wrong:

Here is my iRule:

==========================

when RULE_INIT {

 Set the hostname that the client makes request to (do not include protocol)  
set external_hostname "externalsite.com"  

 Set the hostname that the BIG-IP will rewrite requests to  
set internal_hostname "internalsite.com"  

when CLIENT_ACCEPTED { assign default pool to variable once 3WHS is complete. set default_pool [LB::server pool] }

when HTTP_REQUEST {

log local6.notice "External request from [IP::client_addr] -> [HTTP::host][HTTP::uri]"  
if { ([string tolower [HTTP::uri]] eq "/foobar") } {
    HTTP::header replace Host "$internal_hostname"
pool internal_pool
log local6.notice "External request header rewrite [IP::client_addr] -> [HTTP::host][HTTP::uri]"
} else { 
    pool $default_pool
}

} when HTTP_RESPONSE { if { [HTTP::status] == 302 } { switch [string tolower [HTTP::header Location]] { "$&internal_hostname" { HTTP::header replace Location "&external_hostname" } }

} }

Thank You.

  • Hi,

    here an rule example :

    when RULE_INIT {
        set external_hostname "externalsite.com"  
        set internal_hostname "internalsite.com"  
    }
    when CLIENT_ACCEPTED { 
        set default_pool [LB::server pool] 
    } 
    when HTTP_REQUEST {
         Disable the stream filter for requests
        STREAM::disable
    
         Remove this header to prevent server from compression response
        HTTP::header remove Accept-Encoding
    
        if { ([string tolower [HTTP::path]] eq "/foobar") } {
            HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]] 
            pool internal_pool
        } else { 
            pool $default_pool
        }
    }
    when HTTP_RESPONSE {
         Rewrite the Location header for redirects 
        if { [HTTP::header exists Location] }{ 
            HTTP::header replace Location [string map {$external_hostname $internal_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 "@xyz.company.com@abc.company.com@" 
    
             Enable the stream filter 
            STREAM::enable 
        } 
    }
    

23 Replies

  • Try this (untested):

    when RULE_INIT {
    set external_hostname "externalsite.com"  
    set internal_hostname "internalsite.com"  
    
    when CLIENT_ACCEPTED { 
    set default_pool [LB::server pool] 
    }
    
    when HTTP_REQUEST {
    if { ([string tolower [HTTP::uri]] eq "/foobar") } {
        HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]] pool internal_pool
    } else { 
        pool $default_pool
    }
    
    when HTTP_RESPONSE {
    if { [HTTP::header values Location] contains "$internal_hostname" } {
    HTTP::header replace Location [string map {$internal_hostname $external_hostname} [HTTP::header value Location]]
    }
    }
    
  • Hi,

    here an rule example :

    when RULE_INIT {
        set external_hostname "externalsite.com"  
        set internal_hostname "internalsite.com"  
    }
    when CLIENT_ACCEPTED { 
        set default_pool [LB::server pool] 
    } 
    when HTTP_REQUEST {
         Disable the stream filter for requests
        STREAM::disable
    
         Remove this header to prevent server from compression response
        HTTP::header remove Accept-Encoding
    
        if { ([string tolower [HTTP::path]] eq "/foobar") } {
            HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]] 
            pool internal_pool
        } else { 
            pool $default_pool
        }
    }
    when HTTP_RESPONSE {
         Rewrite the Location header for redirects 
        if { [HTTP::header exists Location] }{ 
            HTTP::header replace Location [string map {$external_hostname $internal_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 "@xyz.company.com@abc.company.com@" 
    
             Enable the stream filter 
            STREAM::enable 
        } 
    }
    
    • dihris_116090's avatar
      dihris_116090
      Icon for Nimbostratus rankNimbostratus
      Hi Yann, thank you for your response. I've created stream profile and added to the VS. Installed the iRule though it does not seem to be working. As with the iRule from Odaah I do not see the header getting changed. I take it under STREAM::expression I neeed to change the find/replace string to @$internalsite.com@$externalsite.com@ ? What logging should I put to see exactly where the iRule brakes?
    • Yann_Desmarest_'s avatar
      Yann_Desmarest_
      Icon for Nacreous rankNacreous
      Hi, you can check in the ltm log if there is some tcl errors from this irule.
  • Hi,

    here an rule example :

    when RULE_INIT {
        set external_hostname "externalsite.com"  
        set internal_hostname "internalsite.com"  
    }
    when CLIENT_ACCEPTED { 
        set default_pool [LB::server pool] 
    } 
    when HTTP_REQUEST {
         Disable the stream filter for requests
        STREAM::disable
    
         Remove this header to prevent server from compression response
        HTTP::header remove Accept-Encoding
    
        if { ([string tolower [HTTP::path]] eq "/foobar") } {
            HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]] 
            pool internal_pool
        } else { 
            pool $default_pool
        }
    }
    when HTTP_RESPONSE {
         Rewrite the Location header for redirects 
        if { [HTTP::header exists Location] }{ 
            HTTP::header replace Location [string map {$external_hostname $internal_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 "@xyz.company.com@abc.company.com@" 
    
             Enable the stream filter 
            STREAM::enable 
        } 
    }
    
    • dihris_116090's avatar
      dihris_116090
      Icon for Nimbostratus rankNimbostratus
      Hi Yann, thank you for your response. I've created stream profile and added to the VS. Installed the iRule though it does not seem to be working. As with the iRule from Odaah I do not see the header getting changed. I take it under STREAM::expression I neeed to change the find/replace string to @$internalsite.com@$externalsite.com@ ? What logging should I put to see exactly where the iRule brakes?
    • Yann_Desmarest's avatar
      Yann_Desmarest
      Icon for Cirrus rankCirrus
      Hi, you can check in the ltm log if there is some tcl errors from this irule.
  • Hi,

    In the HTTP_REQUEST event, try to replace this :

    HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]]

    by

    HTTP::header replace "Host" [string map "$external_hostname $internal_hostname" [HTTP::host]]

    • Yann_Desmarest's avatar
      Yann_Desmarest
      Icon for Cirrus rankCirrus
      or use : HTTP::header replace "Host" [string map -nocase [list $external_hostname $internal_hostname] [HTTP::host]]
    • dihris_116090's avatar
      dihris_116090
      Icon for Nimbostratus rankNimbostratus
      In both cases I'm getting TCL error: err tmm1[32619]: 01220001:3: TCL error: /Common/test_3 - can't read "external_hostname": no such variable while executing "string map "$external_hostname $internal_hostname" [HTTP::host]" ==================== err tmm1[32619]: 01220001:3: TCL error: /Common/test_3 - can't read "external_hostname": no such variable while executing "list $external_hostname $internal_hostname" I did verify that the variables I set when initiating the iRule do match. My internal host does have a bit non standard name: foo-bar-baz.qux.mycompany.io can that be creating an issue?
  • Hi,

    In the HTTP_REQUEST event, try to replace this :

    HTTP::host [string map {$external_hostname $internal_hostname} [HTTP::host]]

    by

    HTTP::header replace "Host" [string map "$external_hostname $internal_hostname" [HTTP::host]]

    • Yann_Desmarest_'s avatar
      Yann_Desmarest_
      Icon for Nacreous rankNacreous
      or use : HTTP::header replace "Host" [string map -nocase [list $external_hostname $internal_hostname] [HTTP::host]]
    • dihris_116090's avatar
      dihris_116090
      Icon for Nimbostratus rankNimbostratus
      In both cases I'm getting TCL error: err tmm1[32619]: 01220001:3: TCL error: /Common/test_3 - can't read "external_hostname": no such variable while executing "string map "$external_hostname $internal_hostname" [HTTP::host]" ==================== err tmm1[32619]: 01220001:3: TCL error: /Common/test_3 - can't read "external_hostname": no such variable while executing "list $external_hostname $internal_hostname" I did verify that the variables I set when initiating the iRule do match. My internal host does have a bit non standard name: foo-bar-baz.qux.mycompany.io can that be creating an issue?