Forum Discussion

jba3126's avatar
jba3126
Icon for Cirrus rankCirrus
May 22, 2019

iRule to redirect URI based on host using Datagroup

I'm experiencing a strange looping condition while testing an iRule to match host to redirect to a specific URI in a datagroup. I'm uncertain if this is a web server configuration or something in the iRule?

 

Host Host + URI

cc.site.com = cc.site.com/cc/

cc.site1.com = cc.site1.com/cc1/

 

FYI: The final URI will look something like /cc/cc?site=abc123

 

DG:

ltm data-group internal CC-Host-to-URI-Redirect-DG {

   records {

       cc.site.com {

           data /cc/

       }

       cc.site1.com {

           data /cc1/

       }

   }

   type string

}

 

iRule

when HTTP_REQUEST {

    if { [ class match [HTTP::host] equals CC-Host-to-URI-Redirect-DG ] } {

       set new_URI [ class match -value [HTTP::host] equals CC-Host-to-URI-Redirect-DG ]

       HTTP::redirect "https://[getfield [HTTP::host] ":" 1]$new_URI

    }

}

 

cURL

Note: Output limited

# curl -vik --resolve cc.site.com:443:10.10.10.18 https://cc.site.com

> GET / HTTP/1.1

> Host: cc.site.com

> User-Agent: curl/7.47.1

> Accept: */*

>

* HTTP 1.0, assume close after body

< HTTP/1.0 301 Moved Permanently

HTTP/1.0 301 Moved Permanently

< new: server

new: server

< location: https://cc.site.com/cc/

location: https://cc.site.com/cc/

< Server: BigIP

Server: BigIP

* HTTP/1.0 connection set to keep alive!

< Connection: Keep-Alive

Connection: Keep-Alive

< Content-Length: 0

Content-Length: 0

 

The response from cURL looks fine; however in a browser this loops until Chrome gives up then throws it back to the main page again and loops again.

 

/jeff

6 Replies

  • Curl works, because curl will only do one request. After the first redirect, the following check will match again:

    if { [ class match [HTTP::host] equals CC-Host-to-URI-Redirect-DG ] } {

    Because it matches, it will do a redirect again. This causes the loop in Chrome. You'll need to make this if statement more specific. For example also check if [HTTP::uri] equals '/'.

  • Nazir's avatar
    Nazir
    Icon for Nimbostratus rankNimbostratus

    You need to check whether URI is not same as in Data-Group. If it matches no redirection request has to be forwarded to pool.

     

  • Hello,

    So in fact you have to redirect user only when the request URI is different frome the uri in your DG, so try this irule:

    when HTTP_REQUEST {
     set host [string tolower [HTTP::host]]
     set uri [string tolower [HTTP::uri]]
      
    if { [ class match $host equals CC-Host-to-URI-Redirect-DG ] } {
     	set new_URI [ class match -value $host equals CC-Host-to-URI-Redirect-DG ]
     	if {!($uri starts_with $new_URI)}{
    		HTTP::redirect "https://[getfield $host ":" 1]$new_URI"
     	}
    }
    }

    Additional important point, If you use different POOl by hostname or URI, don't forget to set an OneConnect profile in order to detach http request.

    let me know if you need more details.

    regards

    • jba3126's avatar
      jba3126
      Icon for Cirrus rankCirrus

      All, Thank you for the replies and apologies for the delayed response. It was a long weekend and I'm still trying to get used to the new DevCentral.

       

      With that said, I see what you mean about the two match conditions. Also with setting both the HOST and URI. Unfortunately I'm still getting a loop condition when trying the iRule suggested above and matching the plain / prior to redirecting. To rule out caching of the condition I started running Chrome in Incognito mode. I also did attach the default OneConnect profile and that see to work but then I started looping when trying the other URL. Another issue I encountered is if I pasted the full URL it kicked me back to the default which is fine on the initial connection, but don't want that to happen if someone clicks on a link within the page.

       

      Use case:

      Detect host and redirect to specific URI defined in a datagroup. In short I want to be able to use one VS to host multiple specific instances of the same application that are defined with content specific to the URI. I'm going to work on adding logging and use Fiddler to see if I can catch where the loop is.

       

      Regards,

       

      /jeff

  • FYI, I got the following to work via traffic policy; however it's not using the datagroup which is what I want to have a way to easily add new host to URI mappings without having to add another Rule in the case of traffic policies or iRules. So as Niels van Sluis suggested it seems to be an issue with [HTTP::uri] equals '/'. As soon as I added this to the traffic policy my redirect loop stopped.

     

    Static Traffic Policy

    ltm policy CC-Host-to-URI-Redirect-Policy {

       controls { forwarding }

       description "Redirect URIs based on Host"

       last-modified 2019-05-28:15:10:00

       requires { http }

       rules {

           CC-Site-Host-to-URI-Redirect-Rule {

               actions {

                   0 {

                       http-reply

                       redirect

                       location https://cc.site.com/cc/

                   }

               }

               conditions {

                   0 {

                       http-host

                       host

                       values { cc.site.com }

                   }

                   1 {

                       http-uri

                       path

                       values { / }

                   }

               }

               ordinal 1

           }

           CC-Site1-Host-to-URI-Redirect-Rule {

               actions {

                   0 {

                       http-reply

                       redirect

                       location https://cc.site1.com/cc1/

                   }

               }

               conditions {

                   0 {

                       http-host

                       host

                       values { cc.site1.com }

                   }

                   1 {

                       http-uri

                       path

                       values { / }

                   }

               }

           }

       }

       status published

       strategy first-match

    }

     

     

  • Tae's avatar
    Tae
    Icon for Nimbostratus rankNimbostratus

    Just remember not use more than 128 characters long due to following bugs which F5 has no fix nor workaround.

    Bug ID 802721: Virtual Server iRule does not match an External Data Group key that's 128 characters long https://urldefense.proofpoint.com/v2/url?u=https-3A__cdn.f5.com_product_bugtracker_ID802721.html&d=DwICaQ&c=jOURTkCZzT8tVB5xPEYIm3YJGoxoTaQsQPzPKJGaWbo&r=8uinM8xMeFrMOkDZ2phZYseX0oh_en0gA_JkLK5cleM&m=FkYPCWdfw-iodN4Uru6InEH_3Z-LtRW-hP8bRXbPYhY&s=eDlupQDJVZn2lpMEDOs2wikwqHzD3g8n2Wl7Qc4n5m4&e=