Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

iRule to redirect URI based on host using Datagroup

jba3126
Cirrus
Cirrus

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 6

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
Nimbostratus
Nimbostratus

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.

 

youssef1
Cumulonimbus
Cumulonimbus

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

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

jba3126
Cirrus
Cirrus

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
Nimbostratus
Nimbostratus

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=D...