Forum Discussion
Chris_Chaloux_1
Nimbostratus
Dec 03, 2008LTM Maint. Page issue
All -
I am trying to set up the LTM Maintenace Page example and I'm running into an issue. I have set up the rule exactly as described in the document (http://devcentral.f5.com/Wiki/default.aspx/iRules/LTMMaintenancePage.html).
The issue I am having is that instead of the lindex html stream being returned, it is returning the location of the class file to the browser. When I invoke the rule by going after the VIP from my browser, the only display I get is:
/var/class/maint.index.html.class
Thats it! It seems like either a variable isnt being invoked correctly, or for some reason it is interpreting the call to the class file as a literal.
My iRule reads like this:
when HTTP_REQUEST {
Service requests for files (URIs) from the maintenance page
Note that we always service these pages, even if the http_pool is up
set maint_prefix "/maintenancepage"
set maint_len [string length $maint_prefix]
set uri [HTTP::uri]
log local0. "redirect: [HTTP::uri]"
if { $uri equals ${::maint_prefix} } {
HTTP::respond 301 "Location" "${::maint_prefix}/"
return
}
if { $uri starts_with "${::maint_prefix}/" } {
trim off the maintenance prefix
set uri [string range $uri $::maint_len end]
Return the requested page
log local0. "respond: [lindex $::maint_index_html 0]"
switch $uri {
"/" -
"/index.html" { HTTP::respond 200 content [lindex $::maint_index_html 0] "Content-Type" "text/html" }
"/logo.png" { HTTP::respond 200 content [b64decode [lindex $::maint_logo_png 0]] "Content-Type" "image/png" }
default { HTTP::respond 404 }
}
return
}
If the all members in the default pool are down, redirect to the maintenance page
if { [active_members [LB::server pool]] < 1 } {
HTTP::redirect "${::maint_prefix}/index.html"
return
}
}
Does anyone see whats going on? This is driving me nuts!!
Thanks,
Chris
15 Replies
- hoolio
Cirrostratus
Hi Chris,
I think one issue is that you're using local variables in HTTP_REQUEST when setting the maint_prefix string (set maint_prefix "/maintenancepage"), but referencing a global variable (if {$uri equals ${::maint_prefix}}...) in the rest of the rule. Try changing the global variables to locals and see if you get better results. The Codeshare example declares the maint_prefix and maint_len variables in the RULE_INIT event. So they're implicitly defined as globals, even though they don't use the double colon in the name: 'set ::global_var value'.
If you make that change and it still doesn't work, can you log the output of [lindex $::maint_index_html 0]? Do you get the correct HTML string? If not, can you post what you see? Can you run 'b class main_index_html list' and post the output?
There are some other fixes/optimizations you could make to the example. You could save a few steps by using string map to trim off the maint_prefix. So instead of:set maint_prefix "/maintenancepage" set maint_len [string length $maint_prefix] set uri [HTTP::uri] ... set uri [string range $uri $::maint_len end]
to:set maint_prefix "/maintenancepage" set uri [HTTP::uri] ... set uri [string map [list $maint_prefix ""] $uri]
Also, the redirect location should be an absolute URL (https://www.example.com/redirect_location.html) not just the path (/redirect_location.html):
ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt
14.30 Location
The Location response-header field is used to redirect the recipient
to a location other than the Request-URI for completion of the
request or identification of a new resource. For 201 (Created)
responses, the Location is that of the new resource which was created
by the request. For 3xx responses, the location SHOULD indicate the
server's preferred URI for automatic redirection to the resource. The
field value consists of a single absolute URI.
Location = "Location" ":" absoluteURI
An example is:
Location: http://www.w3.org/pub/WWW/People.html
Aaron - Chris_Chaloux_1
Nimbostratus
Hi Aaron! Thanks again for the reply. You've always been extremely helpful.
I think I see a bit more with what is going on.
In the log output, I'm seeing:
can't read "maint_index_html": no such variable
I have it defined as class on the LTM, as a string and the file it is looking for is in /var/class. I have opened up the permissions just to make sure but no luck. I'm still not sure that I have made all of the variables global. Also, Where is the $::maint_index_html variable set, or becuase it is defined with the $:: it knows its a class? - hoolio
Cirrostratus
What is your class name that contains the HTML? Is it named exactly maint_index_html? If so you can reference it using $::maint_index_html. Can you try this rule and see if it works for you?when HTTP_REQUEST { Test the maint_index_html class if {[info exists ::maint_index_html]}{ log local0. "\[lindex \$::maint_index_html 0\]: [lindex $::maint_index_html 0]" } else { log local0. "\$::maint_index_html doesn't exist!" } Service requests for files (URIs) from the maintenance page Note that we always service these pages, even if the http_pool is up set maint_prefix "/maintenancepage" set maint_len [string length $maint_prefix] set uri [HTTP::uri] log local0. "redirect: [HTTP::uri]" if { $uri equals $maint_prefix } { HTTP::respond 301 "Location" "$maint_prefix/" } elseif { $uri starts_with "$maint_prefix/" } { Return the requested page switch $uri { "$maint_prefix/" - "$maint_prefix/index.html" { HTTP::respond 200 content [lindex $::maint_index_html 0] "Content-Type" "text/html" } "$maint_prefix/logo.png" { HTTP::respond 200 content [b64decode [lindex $::maint_logo_png 0]] "Content-Type" "image/png" } default { HTTP::respond 404 } } return } If the all members in the default pool are down, redirect to the maintenance page if { [active_members [LB::server pool]] < 1 } { HTTP::redirect "$maint_prefix/index.html" } }
If not, can you check the /var/log/ltm file for any errors or debug?
Thanks,
Aaron - Chris_Chaloux_1
Nimbostratus
Well! Closer...I added your updated code and now get the following in the LTM log:
TCL error: (rule name) - can't read "maint_prefix": no such variable while executing "string length $maint_prefix" - hoolio
Cirrostratus
Here is a tested version which uses local variables. I changed the class names to end with _class so it's a bit more clear that they're not standard global variables. I also changed the logic so that only one test would be done if the request isn't for a maintenance page. This should make the rule slightly more efficient for the majority of requests.
Can you update your class names to match these and give the rule below a try?
Thanks,
Aaron
Class containing the HTML:class maint_index_html_class { type string filename "/var/class/maint.index.html.class" }
Class containing the base64 encoded image:class maint_index_logo_class { type string filename "/var/class/maint.logo.png.class" }
iRule which references the HTML and logo class:when HTTP_REQUEST { Service requests for files (URIs) from the maintenance page Note that we always service these pages, even if the http_pool is up set maint_prefix "/maintenancepage" log local0. "New request to: [HTTP::uri]" if { [HTTP::uri] starts_with "$maint_prefix" } { Strip off the $maint_prefix from the URI as you can't easily do variable expansion within a switch statement. Note that requests for the exact maintenance URI will be set to a null string, so handle null in the first switch case. set uri [string map [list $maint_prefix ""] [HTTP::uri]] Return the requested page switch -- $uri { "" { log local0. "Request for $maint_prefix. Redirecting to $maint_prefix/" HTTP::redirect "$maint_prefix/index.html" } "/" - "/index.html" { log local0. "Request for index. Responding with content: [lindex $::maint_index_html_class 0]" HTTP::respond 200 content [lindex $::maint_index_html_class 0] "Content-Type" "text/html" } "/logo.png" { log local0. "Request for logo.png. Responding with binary content" HTTP::respond 200 content [b64decode [lindex $::maint_logo_png_class 0]] "Content-Type" "image/png" } default { log local0. "Unrecognized request to URI: [HTTP::uri]" HTTP::respond 404 content "Unrecognized request to [HTTP::uri]" "Content-Type" "text/html" } } return } If the all members in the default pool are down, redirect to the maintenance page if { [active_members [LB::server pool]] < 1 } { HTTP::redirect "$maint_prefix/index.html" } } - Chris_Chaloux_1
Nimbostratus
Interesting!!
Why is it retuning the class file name to the browser instead of the contents of it!!
LTM logs shows:
Dec 5 08:54:11 tmm tmm[1709]: Rule fieldnet_oos : New request to: /maintenancepage/index.html
Dec 5 08:54:11 tmm tmm[1709]: Rule fieldnet_oos : Request for index. Responding with content: /var/class/maint.index.html.class
Browser "view source" contents:
/var/class/maint.index.html.class
What am I missing!?! Is there a version issue or something here?
Thanks again!! - hoolio
Cirrostratus
I'd guess that your class isn't defined correctly or the external file actually contains /var/class/maint.index.html.class. If you list the class definition you should see something like this:b class maint_index_html_class list all class maint_index_html_class { type string filename "/var/class/maint.index.html.class" mode rw partition Common "Maintenance pageSorry! This site is down for maintenance." none none }
Can you post what you see?
Thanks,
Aaron - Nit_67494
Nimbostratus
Hi All,
Any body can help me to create the i-rules via GUI, I have tried to create it by my self, but looks like the maintenance page is not working.
Thanks
- JRahm
Admin
Have you checked out Kirk's sorry page generator? Does all the work for you:
http://devcentral.f5.com/weblogs/jason/archive/2009/05/12/host-that-sorry-page-on-your-big-ip.aspx Click Here - hoolio
Cirrostratus
Hi Nit,
Which LTM version are you running? What have you configured and what is not working?
Aaron
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects
