Forum Discussion
http rewrite and pool selection based on method
We have a requirement to perform URI rewrites for specific paths and direct that request to the appropriate pool. As an added bonus we also need to inspect the http method used to make sure we are sending to the appropriate pool.
I've came up with the following rule so far but getting a compile error error: /Common/irulename:10: error: [command is not valid in the current scope][if { [string tolower [HTTP::method]] eq "get" } {
Please help and also let me know if there is a better way to write this as i'm still learning irules.
first uri check to determine if it matches
method can be get or put, rewrite URI and route to appropriate pool
when HTTP_REQUEST {
if {( [string tolower [HTTP::uri]] eq "/IMSWeb/IMSServlet" ) } {
HTTP::uri "/ReservationService/IMSServlet"
pool pool1.tcp.8780
}
}
check to determine appropriate method, perform switch statement
if { [string tolower [HTTP::method]] eq "get" } {
method is get, need to rewrite URI and route to appropriate pool
switch -glob [string tolower [HTTP::uri] ] {
"/IMSWeb/rest/services/inventory" {
HTTP::uri "/ReservationService/IMSServlet"
pool pool1.tcp.8780
}
"/IMSWeb/Lookup" {
HTTP::uri "/ReservationService/UI/invLookUp"
pool pool1.tcp.8780
}
}
}
else { [string tolower [HTTP::method]] eq "put" } {
method is put, need to rewrite host & URI and route to appropriate pool
switch -glob [string tolower [HTTP::uri] ] {
"/IMSWeb/rest/services/item" {
HTTP::host "foo.com"
HTTP::uri "/iasserver/rest/services/item"
pool pool2.tcp.80
}
"/IMSWeb/rest/services/inventory" {
HTTP::host "foo.com"
HTTP::uri "/iasserver/rest/services/inventory"
pool pool2.tcp.80
}
}
}
}
6 Replies
- Arie
Altostratus
You have a wayward closing brace on line 6, which closes the event "HTTP_REQUEST". HTTP::method is therefore executed outside of that scope.
- Arie
Altostratus
I can't test it right now, but try this:
when HTTP_REQUEST { if {( [string tolower [HTTP::uri]] eq "/IMSWeb/IMSServlet" ) } { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } check to determine appropriate method, perform switch statement if { [string tolower [HTTP::method]] eq "get" } { method is get, need to rewrite URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/inventory" { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } "/IMSWeb/Lookup" { HTTP::uri "/ReservationService/UI/invLookUp" pool pool1.tcp.8780 } } } else { [string tolower [HTTP::method]] eq "put" } { method is put, need to rewrite host & URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/item" { HTTP::host "foo.com" HTTP::uri "/iasserver/rest/services/item" pool pool2.tcp.80 } "/IMSWeb/rest/services/inventory" { HTTP::host "foo.com" HTTP::uri "/iasserver/rest/services/inventory" pool pool2.tcp.80 } } } } - minnoce944
Nimbostratus
thanks for the response, but still getting compile errors:
01070151:3: Rule [/Common/meh] error: /Common/meh:9: error: [undefined procedure:
method is put, need to rewrite host & URI and route to appropriate poolHere is what I'm using:
first uri check to determine if it matches method can be get or put, rewrite URI and route to appropriate pool when HTTP_REQUEST { if {( [string tolower [HTTP::uri]] eq "/IMSWeb/IMSServlet" ) } { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } check to determine appropriate method, perform switch statement if { [string tolower [HTTP::method]] eq "get" } { method is get, need to rewrite URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/inventory" { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } "/IMSWeb/Lookup" { HTTP::uri "/ReservationService/UI/invLookUp" pool pool1.tcp.8780 } } } else { [string tolower [HTTP::method]] eq "put" } { method is put, need to rewrite host & URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/item" { HTTP::host "foo.com" HTTP::uri "/iasserver/rest/services/item" pool pool2.tcp.80 } "/IMSWeb/rest/services/inventory" { HTTP::host "foo.com" HTTP::uri "/iasserver/rest/services/inventory" pool pool2.tcp.80 } } } } - minnoce944
Nimbostratus
I changed else to elseif and http::host to http::header replace Host since i'm on ver 11.4. It compiles fine now. I'll post back after my testing results.
Below is updated version:
first uri check to determine if it matches method can be get or put, rewrite URI and route to appropriate pool when HTTP_REQUEST { if {( [string tolower [HTTP::uri]] eq "/IMSWeb/IMSServlet" ) } { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } check to determine appropriate method, perform switch statement if { [string tolower [HTTP::method]] eq "get" } { method is get, need to rewrite URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/inventory" { HTTP::uri "/ReservationService/IMSServlet" pool pool1.tcp.8780 } "/IMSWeb/Lookup" { HTTP::uri "/ReservationService/UI/invLookUp" pool pool1.tcp.8780 } } } elseif { [string tolower [HTTP::method]] eq "put" } { method is put, need to rewrite host & URI and route to appropriate pool switch -glob [string tolower [HTTP::uri] ] { "/IMSWeb/rest/services/item" { HTTP::header replace Host "pool2" HTTP::uri "/iasserver/rest/services/item" pool pool2.tcp.80 } "/IMSWeb/rest/services/inventory" { HTTP::header replace Host "pool2" HTTP::uri "/iasserver/rest/services/inventory" pool pool2.tcp.80 } } } } - minnoce944
Nimbostratus
ok back again..after fixing a few case sensitivity issues with my original code, this is working for the most part. I'm currently having issues with replacing the http host with a new value. I'm currently using 'http::header replace Host' but the new value doesn't appear to be used from my debug output.
Here is the curl command i'm using with the original request. curl -X put meh http://pool1:8380/IMSWeb/rest/services/inventory
Here is the irule debug output: Jul 31 17:13:20 lb-core-01 info tmm1[10029]: Rule /Common/pool1.tcp.8380.irule : original request:pool1:8380:/IMSWeb/rest/services/inventory Jul 31 17:13:20 lb-core-01 info tmm1[10029]: Rule /Common/pool1.tcp.8380.irule : using put method Jul 31 17:13:20 lb-core-01 info tmm1[10029]: Rule /Common/pool1.tcp.8380.irule : processing method put for /imsweb/rest/services/inventory Jul 31 17:13:20 lb-core-01 info tmm1[10029]: Rule /Common/pool1.tcp.8380.irule : The new host and uri is: pool1:8380:/iasserver/rest/services/inventory
As you can see the URI value is updated correctly from /IMSWeb/rest/services/inventory to /iasserver/rest/services/inventory but the host value is still the original value.
How can i fix this? Also, it looks like i'll also need to modify the port as well since i'm sending this traffic to port 80 vs 8380. I would imagine once i get the correct procedure to rewrite the host i could just add :80 to the end of that.
Thanks,
--Mike
Here is my updated irule:
pool1.tcp.8380.irule v1.0 7-31-2014 xxx first uri check to determine if it matches method can be get or put, rewrite URI and route to appropriate pool when HTTP_REQUEST { log local0. "original request:[HTTP::host]:[HTTP::uri]" if {( [string tolower [HTTP::uri]] eq "/imsweb/imsservlet" ) } { log local0. "condition met - routed to pool1.tcp.8780" HTTP::uri "/reservationservice/imsservlet" pool pool1.tcp.8780 } check to determine appropriate method, perform switch statement if { [string tolower [HTTP::method]] eq "get" } { method is get, need to rewrite URI and route to appropriate pool log local0. "using get method" switch -glob [string tolower [HTTP::uri] ] { "/imsweb/rest/services/inventory" { log local0. "processing method get for /imsweb/rest/services/inventory" HTTP::uri "/reservationservice/imsservlet" pool pool1.tcp.8780 } "/imsweb/lookup" { log local0. "processing method get for /imsweb/lookup" HTTP::uri "/reservationservice/ui/invlookup" pool pool1.tcp.8780 } } } elseif { [string tolower [HTTP::method]] eq "put" } { method is put, need to rewrite host & URI and route to appropriate pool log local0. "using put method" switch -glob [string tolower [HTTP::uri] ] { "/imsweb/rest/services/item" { log local0. "processing method put for /imsweb/rest/services/item" HTTP::header replace Host "pool2" HTTP::uri "/iasserver/rest/services/item" pool pool2.tcp.80 } "/imsweb/rest/services/inventory" { log local0. "processing method put for /imsweb/rest/services/inventory" HTTP::header replace Host "pool2" HTTP::uri "/iasserver/rest/services/inventory" log local0. "The new host and uri is: [HTTP::host]:[HTTP::uri]" pool pool2.tcp.80 } } } }- minnoce944
Nimbostratus
Just wanted to close the loop on this one in case anyone comes across this in the future. The 'http::header replace Host' was in fact replacing the host value, it was just the fact i was using the following statement to log this '[HTTP::host]:[HTTP::uri]' when in fact i should be using [HTTP::header values Host]. From my understanding the HTTP::host value would have still contained the original value. This rule is working fine with some additional tweaks for a few other conditions they wanted to check for and route based on.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com