For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

JeffRay_129268's avatar
JeffRay_129268
Icon for Nimbostratus rankNimbostratus
Nov 22, 2015

irule based redirection issue

Dear Members, I have a problem of language redirection loop. As per code mentioned below, Preferred Language is detected (i.e fr (french) in browser and redirected by ltm but this redirection goes into loop instead of request forwarded to server to retrieve the page by client. Seems every time ltm gets redirected URL from client it checks language and does same redirection which ends in continuous loop (snippet below of redirection from ltm). While for other preferred language when selected e.g en it works fine as it is a default in rule. It is really painful for me to get rid of this loop and have no idea why it is not working. I need your expertise to help me get rid of this nasty loop. Thanks.

 

Response    HTTP/1.0 302 Found
Location    https://www.mylocalnet.us/fr/pages/default.aspx
Server  BigIP

when HTTP_REQUEST {

if { [string tolower [HTTP::path]] equals "/atd/atd.xml" } {
            HTTP::respond 301 "Location" "https://atd.mylocalnet.us/atd/atd.xml"

} elseif { [HTTP::header "Accept-Language"] starts_with "fr" }  {
            HTTP::redirect "https://www.mylocalnet.us/fr/pages/default.aspx"

   } elseif { [string tolower [HTTP::path]] equals "/" } {
            HTTP::redirect "https://www.mylocalnet.us/en/pages/default.aspx"
}
}

 

19 Replies

  • Your irule can't be good with IF ELSEIF ... There is 301 in the first and redirect in the 2 following.

     

    Please let us know what do you want exactly.

     

  • there's one extra negation in your condition. please look at my previous post for the correct one.

     

  • Currently client sends URL request mylocalnet.us which is redirected to https with www code which is code 301. Once redirected to https://www.mylocalnet.us it is offloaded on ltm and request is sent to Web Server. Web server responds 302 https://www.mylocalnet.us/pages/variationroot.aspx which is used for language detection. If FR detected, server replies https://www.mylocalnet.us/fr/pages/default.aspx or with /en per language support. Actual purpose is to avoid multiple redirections on server side and perform these operations on ltm to expedite response time. Sharing with you unmodified code.

     

        when HTTP_REQUEST {
    
             STREAM::disable
             redirect atd requests to atd site
        if { [string tolower [HTTP::path]] equals "/atd/atd.xml" } {
    
         HTTP::respond 301 "Location" "https://atd.mylocalnet.us/atd/atd.xml"
    
             redirect http://mylocalnet.us to https://www.mylocalnet.us along with any uri
     } elseif { [string tolower [HTTP::host]] equals "mylocalnet.us" } {
        HTTP::respond 301 "Location" "https://www.mylocalnet.us[string tolower [HTTP::uri]]"
    } 
      switch -glob [string tolower [HTTP::path]] {
                "/en/sitemap.xml*" {
                HTTP::uri "/en-sitemap.xml"
                }
                "/fr/sitemap.xml*" {
                HTTP::uri "/fr-sitemap.xml"
                }  
                 }
                 }
            when HTTP_RESPONSE {
             catch and replace redirect headers
            if { [HTTP::header exists Location] } {
        HTTP::header replace Location [string map {"http://" "https://"} [string tolower [HTTP::header Location]]]
         } 
        only look at text data
            if { [HTTP::header Content-Type] contains "text" } {
      create a STREAM expression to replace any http:// with https:// for CDN
    STREAM::expression {@http://bt.mylocal.ae@https://bt.mylocal.ae@ @www.mylocalnet.us@ @http://www.mylocalnet.us@https://www.mylocalnet.us@}
                enable STREAM
                STREAM::enable
            }
        }
  • OK, something like that. If starting page is "/" check language and redirect to the right URI.

     

    when HTTP_REQUEST {
        if { [string tolower [HTTP::path]] equals "/" } {
            if { ![HTTP::path] starts_with "/fr" && ([HTTP::header "Accept-Language"] starts_with "fr") } {
                HTTP::redirect "https://www.mylocalnet.us/fr/pages/default.aspx"
            }
            else { 
                HTTP::redirect "https://www.mylocalnet.us/en/pages/default.aspx" 
            }
        }
    }
    

     

  • Matthieu, please ignore my ignorance. If you could adjust in existing rule since else or if is having deprecated irule error so not able to make the changes. my apologies.

     

  • Like that

     

    when HTTP_REQUEST {
    
         STREAM::disable
         if { [string tolower [HTTP::path]] equals "/" } {
                if { ![HTTP::path] starts_with "/fr" && ([HTTP::header "Accept-Language"] starts_with "fr") } {
                    HTTP::redirect "https://www.mylocalnet.us/fr/pages/default.aspx"
                }
                else { 
                    HTTP::redirect "https://www.mylocalnet.us/en/pages/default.aspx" 
                }
            }
    
            switch -glob [string tolower [HTTP::path]] {
                "/en/sitemap.xml*" {
                    HTTP::uri "/en-sitemap.xml"
                }
                "/fr/sitemap.xml*" {
                    HTTP::uri "/fr-sitemap.xml"
                }  
            }
          }
    
        when HTTP_RESPONSE {
             catch and replace redirect headers
            if { [HTTP::header exists Location] } {
                HTTP::header replace Location [string map {"http://" "https://"} [string tolower [HTTP::header Location]]]
            } 
              only look at text data
            if { [HTTP::header Content-Type] contains "text" } 
                 create a STREAM expression to replace any http:// with https:// for CDN
                STREAM::expression {@http://bt.mylocal.ae@https://bt.mylocal.ae@ @www.mylocalnet.us@ 
        @http://www.mylocalnet.us@https://www.mylocalnet.us@}
                 enable STREAM
                STREAM::enable
            }
        }
    

     

  • I have applied the irule and below is the result. Not sure where the logic is not getting matched in it. Good thing is Loop is stopped but i see only one Get request in a debug after which loop breaks and aborted and redirected to https by ltm . Web page not found in browser . Below is output for your reference.

    URLProtocolMethodResultTypeReceivedTakenInitiatorWait‎‎Start‎‎Request‎‎Response‎‎Cache read‎‎

    http://mylocalnet.us/HTTPGET301143 B94 msnavigate0781600234

    https://www.mylocalnet.us/HTTPS(Aborted)0 B187 msnavigate9418700047

     

     

    Details of Above Messages:
    Request
    --------------------------
    Request               GET / HTTP/1.1
    Accept           text/html, application/xhtml+xml, */*
    Accept-Language  fr,en;q=0.7,en-US;q=0.3
    User-Agent           Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
    Accept-Encoding  gzip, deflate
    Host             mylocalnet.us
    Connection       Keep-Alive
    Cache-Control    no-cache
    
    Response
    --------------------------
    Response             HTTP/1.0 301 Moved Permanently
    Location             https://www.mylocalnet.us/
    Server           BigIP
    Connection           Keep-Alive
    Content-Length   0
    

     

  • OK, the redirection is done by another iRule I suppose. On Virtual Server port 80. When connection arrives on 2nd Virtual Server port 443, you see a Aborted ???

    I made a mistake. Try this by getting https://www.mylocalnet.us/ with an FR and an EN browser.

     

       when HTTP_REQUEST {
    
     STREAM::disable
     if { [string tolower [HTTP::path]] equals "/" } {
            if { [HTTP::header "Accept-Language"] starts_with "fr" } {
                HTTP::redirect "https://www.mylocalnet.us/fr/pages/default.aspx"
            }
            else { 
                HTTP::redirect "https://www.mylocalnet.us/en/pages/default.aspx" 
            }
        }
    
        switch -glob [string tolower [HTTP::path]] {
            "/en/sitemap.xml*" {
                HTTP::uri "/en-sitemap.xml"
            }
            "/fr/sitemap.xml*" {
                HTTP::uri "/fr-sitemap.xml"
            }  
        }
      }
    
    when HTTP_RESPONSE {
         catch and replace redirect headers
        if { [HTTP::header exists Location] } {
            HTTP::header replace Location [string map {"http://" "https://"} [string tolower [HTTP::header Location]]]
        } 
          only look at text data
        if { [HTTP::header Content-Type] contains "text" } 
             create a STREAM expression to replace any http:// with https:// for CDN
            STREAM::expression {@http://bt.mylocal.ae@https://bt.mylocal.ae@ @www.mylocalnet.us@ 
    @http://www.mylocalnet.us@https://www.mylocalnet.us@}
             enable STREAM
            STREAM::enable
        }
    }
    

     

  • Matthieu,

     

    You are simply a GENIUS guy :). Very Very Thanks for your extra ordinary and superb support. Very much impressed. Hats Off. I have tested it and it worked like a magic :) .Once again thanks.