Forum Discussion
krelm_52303
Nimbostratus
Nov 20, 2008Changing HTTP Header Host port
Am receiving http requests on a high port (55555) and need to remove this in the header for all requests (so it sends on as port 80).
For example...
Host: www.google.com:55555 change to Host: www.google.com
Host: www.msn.com:55555 change to Host: www.msn.com
I don't know what all the destinations will be, but need to strip of the 55555 port number from each. Thankfully, I we don't need to rewrite any payload traffic, just this header.
What is the most resource efficient way of achieving this with an irule?
TIA
5 Replies
- hoolio
Cirrostratus
Hi there,
You can strip out anything after the : in the host header using the getfield command (Click here) or using scan in an iRule:when HTTP_REQUEST { Replace host header value with everything before the colon HTTP::header replace Host "[getfield [HTTP::host] : 1]" log local0. "[IP::client_addr]:[TCP::client_port]: Replace original host [HTTP::host] with [getfield [HTTP::host] : 1]" }
If the requests won't always have a port, you could check to see if the host header value contains a colon before replacing the value.when HTTP_REQUEST { Check if host value has a colon if {[HTTP::host] contains ":"}{ Replace host header value with everything before the colon HTTP::header replace Host "[getfield [HTTP::host] : 1]" log local0. "[IP::client_addr]:[TCP::client_port]: Replace original host [HTTP::host] with [getfield [HTTP::host] : 1]" } }
Here is an example using scan (Click hereπwhen HTTP_REQUEST { Scan the host header value. Save the results to $host and $port if there is a colon in the header value if {[scan [HTTP::host] {%[a-zA-Z_.-]:%d} host port] == 2}{ HTTP::header replace Host $host } }
I'm not sure whether scan would be more efficient than getfield. You could use the timing command to test this:
Timing command Click here, Timing article Click here
Aaron - krelm_52303
Nimbostratus
Thanks Aaron - great info as ever!
I used the first example, and the Host header is being forwarded correctly without the port, so all good there. However, the Request URI needs to have the port stripped out too. How would I do this as well?
Thanks again. - hoolio
Cirrostratus
Is the app including the port number in redirects? If so, you can try rewriting the redirects using the HTTP profile option. Or you can use an iRule:when HTTP_RESPONSE { Check if response is a redirect if {[HTTP::is_redirect]}{ Replace :55555/ with / in the Location header HTTP::header replace Location [string map {:55555/ /} [HTTP::header value Location]] } }
If the port isn't in the Location header, can you explain where you're seeing it?
Aaron - krelm_52303
Nimbostratus
Here's a version that is working for us (changing the Request Host header and URI), but hoping there's an easier way to modify the URI?
when HTTP_REQUEST {
Check if host value has a colon
if {[HTTP::host] contains ":"}{
log local0. "URI: [HTTP::uri]"
set find ":55555"
set replace ""
set uri_old [HTTP::uri]
regsub -all $find $uri_old $replace new_uri
HTTP::uri $new_uri
log local0. "NEW URI: [HTTP::uri]"
Replace host header value with everything before the colon
set new_host [getfield [HTTP::host] ":" 1]
HTTP::header replace "Host" $new_host
log local0. "[IP::client_addr]:[TCP::client_port]: Replace original host [HTTP::host] with [getfield [HTTP::host] ":" 1]"
}
}
Also, as you suggest, it looks like we'll need to modify the HTTP_Response Location header + any other references to objects in the HTTP_Response payload. May need to look at this...
http://devcentral.f5.com/weblogs/Joe/archive/2005/07/27/1398.aspx
Cheers. - hoolio
Cirrostratus
Can you post some anonymized samples of the URI's you want to rewrite? Is the client using an absolute URI? Something like this?
GET http://www.w3.org:55555/pub/WWW/TheProject.html HTTP/1.1
User-Agent: ...
If so, you could use string map instead of regsub. The string function would be more efficient than a regex.
HTTP::uri [string map {:55555/ /} [HTTP::uri]]
If you also need to rewrite the port in response content, you could use a stream filter and STREAM::expression based iRule. This would be more efficient than collecting the response content and performing regex operations on it. You can check the STREAM::expression wiki page (Click here) for examples.
Aaron
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
