Forum Discussion

Nicolas_MENOUX_'s avatar
Nicolas_MENOUX_
Icon for Nimbostratus rankNimbostratus
Apr 29, 2009

STREAM_MATCHED for regexp replace ?

Hi,

 

 

I'm using an IRule to replace Http content coming from our web servers in order to change image relative path to absolute path as described below :

 

 

when HTTP_REQUEST {

 

set host [HTTP::host]

 

}

 

 

 

when HTTP_RESPONSE {

 

if {[HTTP::status] == 200 and [HTTP::header "Content-Type"] contains "text"} {

 

if {$host ends_with ".xxxxx.com"}

 

{

 

STREAM::expression {@'/images/@'http://media.xxxxx.com/images/@}

 

STREAM::enable

 

} elseif {$host ends_with ".yyyyy.com"}

 

 

{

 

STREAM::expression {@'/images/@'http://media.yyyyy.com/images/@}

 

STREAM::enable

 

}

 

}

 

}

 

 

As you could see, I've to duplicate the STREAM::expression for each domain name as I do not know how to insert the $host variable into the replace string.

 

How could I use a single if statement to get a result like :

 

 

{

 

STREAM::expression {@'/images/@'http://media.$host.com/images/@}

 

STREAM::enable

 

}

 

 

DO I need to use STREAM_MATCHED context and if yes how to do it please. Thanks for your help,

 

 

Best Regards,

 

 

Nicolas

 

5 Replies

  • Hi Nicolas,

     

    The curly braces should prevent expansion of variables and interpretation of meta-characters (Click here). Also, due to a bug, you always ensure that double forward slashes (like those in http://) are enclosed in double quotes. And make sure to escape the periods or I think they'll be interpreted as a character repeat in a regex fashion:

     

     

    STREAM::expression "@'/images/@'http://media\.$host\.com/images/@"

     

     

    You only need to use STREAM_MATCHED if you want to log the match or modify the replacement strings.

     

     

    Aaron
  • thank aaron for your quick answer ;-)

     

     

    as stream_matched is quite new for me, what would be the basic script to insert the $host variable ? Thanks.

     

     

    Nicolas
  • Just what you had in your original post:

     
     when HTTP_REQUEST { 
        set host [HTTP::host] 
     } 
     

    You could add a check to see if the host value in the request was null and then use the VIP address or the public IP address if the VIP is an internal IP address:

     
     when HTTP_REQUEST { 
         Check if the client used a host header 
        if {[string length [HTTP::host]}[ 
           set host [HTTP::host] 
        } else { 
            Use the VIP address instead 
           set host [IP::local_addr] 
        } 
     } 
     

    Aaron
  • mmm... I'm sorry I think and I'm sure I was not clear in my previous post :-) Thank you for your answer aaron, but if I want to re-use this $host variable into the stream replacement ? As you said, I could not use the $host within braces in the stream::expression, so could I do the replacement within the stream_matched event to replace the '/images/blablabla by 'http://media.$host.com/images/blablabla ? Do you have a sample to do that ? Stream::replace ? Thanks
  • Here the basic idea in one shot:

     

     

     
     when HTTP_REQUEST { 
      
         Check if the client used a host header 
        if {[string length [HTTP::host]]}{ 
           set host [HTTP::host] 
        } else { 
            Use the VIP address instead 
           set host [IP::local_addr] 
        } 
     } 
     when HTTP_RESPONSE { 
      
         Check if the response was a 200 and text 
        if {[HTTP::status] == 200 and [HTTP::header "Content-Type"] contains "text"} { 
           STREAM::expression "@'/images/@'http://media\.$host\.com/images/@" 
           STREAM::enable 
        } 
           STREAM::disable 
        } 
     }  
     

     

     

    Note that the double quotes allow variable expansion to take place and work around a bug in the LTM code with unquoted //'s.

     

     

    Aaron