Forum Discussion
ukstin
Nimbostratus
Jun 09, 2008conditional redirect (404)
Hi people,
I´m trying to wrote a i-rule to redirect a 404 error based on the url. The i-rule I made is this one:
when HTTP_REQUEST {
set host [HTTP::host]
set url [HTTP::uri] ...
hoolio
Cirrostratus
Jun 10, 2008The host header is only required for HTTP 1.1. If a client sends an HTTP 1.0 (or even 0.9) request, the Host header value wouldn't necessarily be present, but regardless the $host variable should be set to a zero length string. I'm not sure how the runtime error could be triggered for $host not being defined, as it's set on every HTTP request (even if it's to a null value).
Using the rule below, I did some tests on 9.2.4 using netcat. In every test, checking if the $host value contained a string succeeded without a TCL error. Between this post and a related one on the ProxyPass rule (Click here), I'd suggest opening a case with F5 Support. It seems like this might be a bug.
As a workaround, you could add a check to see if $host exists before trying to check if it contains a string:
when HTTP_REQUEST {
set host [HTTP::host]
set url [HTTP::uri]
}
when HTTP_RESPONSE {
if { [HTTP::status] == 404 } {
if {[info exists host]}{
if {$host contains "abcd" } {
HTTP::redirect "http://abcd.otherdomain.com/$url"
} elseif {[info exists host] && $host contains "efg" } {
HTTP::redirect "http://efg.otherdomain.com/$url"
} else {
HTTP::redirect "http://anotherone.com/xyz.html"
}
} else {
$host doesn't exist!
log local0. "[IP::client_addr]:[TCP::client_port]: \$host was not set!?"
}
}
}
Aaron
Example rule which saves the HTTP::host output and checks the value in HTTP_RESPONSE:
when HTTP_REQUEST {
set host [HTTP::host]
log local0. "HTTP version: [HTTP::version], HTTP host: $host, HTTP uri: [HTTP::uri]"
}
when HTTP_RESPONSE {
if { $host contains "www" } {
log local0. "matched $host"
} else {
log local0. "didn't match $host"
}
}
Request with a Host header:
$ nc 192.168.101.40 80
GET /withhost HTTP/1.1
Connection: close
Host: www.example.com
Log output:
Rule log_http_host_rule : HTTP version: 1.1, HTTP host: www.example.com, HTTP uri: /withhost
Rule log_http_host_rule : matched www.example.com
Request without a Host header:
$ nc 192.168.101.40 80
GET /withouthost HTTP/1.0
Log output:
Rule log_http_host_rule : HTTP version: 1.0, HTTP host: , HTTP uri: /withouthost
Rule log_http_host_rule : didn't match
0.9 formatted request:
$ nc 192.168.101.40 80
GET /
Log output:
Rule log_http_host_rule : HTTP version: 0.9, HTTP host: , HTTP uri: /
Rule log_http_host_rule : didn't match
Request with a Host header, but nothing after the colon:
nc 192.168.101.40 80
GET / HTTP/1.0
Host:
Test: value
Log output:
Rule log_http_host_rule : HTTP version: 1.1, HTTP host: Connection: close, HTTP uri: /
Rule log_http_host_rule : didn't match Connection: close
This last one could be considered a bug as well. Apparently the HTTP parser doesn't stop parsing the Host header value at the line terminating CRLF if there isn't a value for the header.
'HTTP::header Host' seems to be more accurate:
when HTTP_REQUEST {
set http_host [HTTP::host]
set http_header_host [HTTP::header Host]
log local0. "HTTP version: [HTTP::version], HTTP host: $http_host, HTTP header Host: $http_header_host, HTTP uri: [HTTP::uri]"
}
when HTTP_RESPONSE {
if { $http_host contains "www" } {
log local0. "http_host matched $http_host"
} else {
log local0. "http_host didn't match $http_host"
}
if { $http_header_host contains "www" } {
log local0. "http_header_host matched $http_header_host"
} else {
log local0. "http_header_host didn't match $http_header_host"
}
}
Request:
$ nc 192.168.101.40 80
GET / HTTP/1.0
Host:
Test: value
Log output shows HTTP::host errantly returns the next header name and value, while HTTP::header Host correctly returns nothing:
Rule log_http_host_rule : HTTP version: 1.0, HTTP host: Test: value, HTTP header Host: , HTTP uri: /
Rule log_http_host_rule : http_host didn't match Test: value
Rule log_http_host_rule : http_header_host didn't match
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