Forum Discussion

Todd_Behrens_20's avatar
Todd_Behrens_20
Icon for Nimbostratus rankNimbostratus
Dec 14, 2017

Insert JavaScript If URL path contains word

Hi Everyone, im kind of newbie when it comes to irules and was hoping someone could help me out. I'm looking to insert a javascript into the header of http response only if a certain word is in the URL path. ive been digging around and found a script that work to insert the javascript like i need but im having issues limiting it to only certain paths.

 

here is the insert code that works;

 

when RULE_INIT {
     Insert IM Token Javascript
    set static::jscript {
        
    }
}          
when HTTP_REQUEST { 
     Disable the stream filter by default 
    STREAM::disable 
    set uri [string tolower [HTTP::uri]] 
}
when HTTP_RESPONSE { 
    if { [HTTP::status] == 200 } {
        if {[HTTP::header value Content-Type] contains "text"} { 
            set stream_find ""
            set stream_find_lower ""
            set stream_repl ""
            set insertJscript 1
             Do not allow the Javascript insertion if the pages end with the following
            switch -glob $uri { 
                "*.ashx*" - 
                "*.asmx*" - 
                "*.axd*" - 
                "*.js*" { 
                    set insertJscript 0 
                }
                default {
                    if { [HTTP::payload] contains "META HTTP-EQUIV=\"Refresh\""} { 
                        set insertJscript 0 
                    }
                }
            }
            if {$insertJscript == 1} { 
                append stream_repl $static::jscript
                append stream_expression "@$stream_find@$stream_repl$stream_find@" 
                append stream_expression "@$stream_find_lower@$stream_repl$stream_find_lower@" 

                STREAM::expression $stream_expression 
                STREAM::enable 
            }
        }
    }
}

i found it here; https://devcentral.f5.com/codeshare?sid=741

 

i tried modifying it restrict it to certain word in the url path but i keeps giving me a reset error when i enable it. word is "anakin"

 

when HTTP_REQUEST { 
     Disable the stream filter by default 
    STREAM::disable 
    if {[string tolower [HTTP::uri]] contains "/anakin" }  {
        set sitepath [string tolower [HTTP::uri]]  
}
}

if anyone can give me pointers it would be greatly appreciated.

 

thanks in advance.

 

8 Replies

  • If the connection is being reset, are you seeing any error messages associated with iRule run-time errors in /var/log/ltm?

     

  • thanks for the reponse. I get an 'cannot read" uri error in the logs when the irule is enabled;

     

    TCL error: /Common/im_token_insert_v1 - can't read "uri": no such variable while executing "switch -glob $uri { ".ashx" - ".asmx" - ".axd" - ".js" { set insertJscript 0 } default { if { [HTTP::p..."

     

  • You named the variable "sitepath" in the HTTP_REQUEST event but are referring to it as "uri" ion the SWITCH statement. Either change "sitepath" to "uri" or "uri" to "sitepath" throughout.

     

  • so i changed the HTTP_REQUEST varible to 'uri' but im getting the same error. here is what the code looks like now;

     

    when HTTP_REQUEST { 
         Disable the stream filter by default 
        STREAM::disable 
        if {[string tolower [HTTP::uri]] contains "anakin" }  {
            set uri [string tolower [HTTP::uri]]
    
    }
    }
    
    when HTTP_RESPONSE { 
        if { [HTTP::status] == 200 } {
            if {[HTTP::header value Content-Type] contains "text"} { 
                set stream_find ""
                set stream_find_lower ""
                set stream_repl ""
                set insertJscript 1
    
                 Do not allow the Javascript insertion if the pages end with the following
                switch -glob $uri { 
                    "*.ashx*" - 
                    "*.asmx*" - 
                    "*.axd*" - 
                    "*.js*" { 
                        set insertJscript 0 
                    }
                    default {
                        if { [HTTP::payload] contains "META HTTP-EQUIV=\"Refresh\""} { 
                            set insertJscript 0 
                        }
                    }
                }
    
                if {$insertJscript == 1} { 
                    append stream_repl $static::jscript
                    append stream_expression "@$stream_find@$stream_repl$stream_find@" 
                    append stream_expression "@$stream_find_lower@$stream_repl$stream_find_lower@" 
    
                    STREAM::expression $stream_expression 
                    STREAM::enable 
                }
            }
        }
    
    }
  • i figured out my issues. i needed to add a statement to not insert the script if the url path isnt there. here is what i did if anyone is interested

    when RULE_INIT {
         Insert  Token Javascript
        set static::jscript {
            
        }
    }   
    
    when HTTP_REQUEST { 
       This is the condition for which requests will be matched against 
      if {[HTTP::uri] contains "/Anakin"} { 
       set enableEum 1 
       } 
       else { 
       set enableEum 0 
       } 
    
       Disable the stream filter for client requests as we are only interested in the server response 
      STREAM::disable 
      set uri [string tolower [HTTP::uri]] 
     } 
    
    
    
    when HTTP_RESPONSE { 
        if {($enableEum == 1) } {
            if { [HTTP::status] == 200 } {
                if {[HTTP::header value Content-Type] contains "text"} { 
                    set stream_find ""
                    set stream_find_lower ""
                    set stream_repl ""
                    set insertJscript 1
    
                     Do not allow the Javascript insertion if the pages end with the following
                    switch -glob $uri { 
                        "*.ashx*" - 
                        "*.asmx*" - 
                        "*.axd*" - 
                        "*.js*" { 
                            set insertJscript 0 
                        }
                        default {
                            if { [HTTP::payload] contains "META HTTP-EQUIV=\"Refresh\""} { 
                                set insertJscript 0 
                            }
                        }
                    }
    
                    if {$insertJscript == 1} { 
                        append stream_repl $static::jscript
                        append stream_expression "@$stream_find@$stream_repl$stream_find@" 
                        append stream_expression "@$stream_find_lower@$stream_repl$stream_find_lower@" 
    
                        STREAM::expression $stream_expression 
                        STREAM::enable 
                    }
                }
            }
        }
    }
    
  • You are conditionally setting the variable named "uri" only if the string "anakin" is present in the HTTP URI. If "anakin" is NOT in the URI, the HTTP_RESPONSE code still executes but there is no "uri" variable. You will have to include some sort of code that instructs the system what to do if "anakin" is not in the URI.

     

  • you can try this code:

     

    In your code, you don't server side http compression. and the stream expression variable is created on every response instead of create it only when the irule is loaded.

     

    when RULE_INIT {
         Insert  Token Javascript
        set jscript {}
         Create the stream expression list and insert in this list all rewrite expressions.
        set static::stream_expression [list]
        lappend static::stream_expression "@@$jscript@"
        lappend static::stream_expression "@@$jscript@"
         create the extension list to not rewrite
        set static::no_rewrite_ext [list ashx asmx axd js]
    }   
    
    when HTTP_REQUEST { 
      Check if the word is included in URI and if request extension support javascript insertion.
        if {[HTTP::uri] contains "/Anakin" && [lsearch $static::no_rewrite_ext [getfield [URI::basename [HTTP::uri]] "." 2]] == -1 } { 
            set insertJscript 1
            HTTP::header remove "Accept-Encoding"
        } else { 
            set insertJscript 0 
        }
       Disable the stream filter for client requests as we are only interested in the server response 
        STREAM::disable 
    } 
    
    when HTTP_RESPONSE { 
        if {$insertJscript && [HTTP::status] == 200 && [HTTP::header value Content-Type] contains "text" && !([HTTP::payload] contains "META HTTP-EQUIV=\"Refresh\"")} { 
            STREAM::expression $static::stream_expression 
            STREAM::enable
        }
    }