Forum Discussion
Sean_Lagerholm_
Nimbostratus
Jun 07, 2006Simple http redirect???
Help, I'm having difficulty with fulfilling a requirement :
The customer wants to type in some url and then gets redirected.
The customer doesn't want to see the redirect in their browser.
It should work like this :
in the browser type : http://somesite.com
The request gets proxied by the BigIP to http://anothersite.com/stuff
(the client never sees the http://anothersite.com/stuff in their browser.
Is this a redirect or a rewrite???
Thanks!!!
12 Replies
- Thomas_Uczekaj_
Nimbostratus
You can do this by the following:
when HTTP_REQUEST {
if { [HTTP::uri] equals "/"} {
HTTP::uri /stuff }
}
However, you will not be able to hide the "/stuff" portion of the URI like the
proxypass will do when using Apache Proxy.
Anyone else have an idea how to do that (hide the change in the URI)?
Tom - Deb_Allen_18Historic F5 AccountTom -
Your code actually will accomplish a backend re-write, transparent to the browser.
Lagerholm -
You'd probably also want to change the Host: header to the new hostname:
and if you want to prepend /stuff to every URI, something like this would work:when HTTP_REQUEST { if { [HTTP::uri] equals "/"} { HTTP::uri /stuff } HTTP::header replace Host: anothersite.com }when HTTP_REQUEST { if { [string length [HTTP::uri]] > 1 } { HTTP::uri /stuff[HTTP::uri] } else { HTTP::uri /stuff } HTTP::header replace Host: anothersite.com } - Sean_Lagerholm_
Nimbostratus
Deb,
I tried the irule, it does append the uri (/stuff) but doesn't strip it for the customer in the browser. We get a 404 error now, which tells me the packets do reach the backend server.
Thanks for the tip.
Back to the drawing board.
Sean - Deb_Allen_18Historic F5 AccountHey guys --
Here's a rule that rewrites both request and the response, emulating the rewrite Apache is doing via ProxyPass & ProxyPassReverse:
The requirements:
* Replace Apache ProxyPass & ProxyPassReverse functionality for bidirectional host and URI re-writes.
** Request: Rewrite host header and prepend application path to request URI
** Response: Replace hostname references to client-facing value, and remove prepended URI path from all URLs in payload.
* A single rule which can be applied to multiple virtual servers would be ideal.
The LTM configuration:
* Create the class containing the virtual server names to which the rule will be applied (follow the example below). The re-write values will be extracted for each virtual to which the rule is applied, allowing you to apply to multiple virtuals. If a record does not exist, the rule logic is bypassed.
* Create the pools of backend server with the appropriate service port and serverssl profile if required.
* Apply default pools and profiles to virtual server as required.
* Create the rule below and apply to the virtual servers where functionality is required.
The rule logic and the traffic flow:
* Requests will be sent to port of pool member with modified Host header from table. (Assumes that backend server expects the port in the Host: header.)
* Requests will be sent cleartext or encrypted to backend server based on existence of serverssl profile on the virtual.
* Links in responses will be re-written with client-facing values for host and URI.
That should be pretty close to what you need. If you run into anomalies, adding some log lines to expose the variable values at different points in the code should help you work it out the rest of the way. But if you get stuck, feel free to post back with questions.class ProxyPass { space delimited row for each virtual to which rule will be applied vs_name backend_host_header backend_uri_prefix virtual1 inside_app1.company.com:7005 /newDir/otherDir virtual2 inside_app2.company.com:7006 /newDir/otherDir } rule ProxyPass { when HTTP_REQUEST { set ppass [findclass [virtual name] $::ProxyPass] if {$ppass == ""}{ log local0. "No ProxyPass class entry found for virtual server \ [virtual name] at [IP::local_addr]:[TCP::local_port]. \ Bypassing rewrite logic." set bypass 1 return } else { set host_clientside [HTTP::header Host] set host_serverside [getfield $ppass " " 1] set uri_prepend [getfield $ppass " " 2] HTTP::uri $uri_prepend[HTTP::uri] HTTP::header replace Host: $host_serverside } } when HTTP_RESPONSE { if { 1 != $bypass }{ set length [HTTP::header Content-Length] HTTP::collect $length regsub -all $host_serverside$uri_prepend [HTTP::payload] $host_clientside newdata HTTP::payload replace 0 $length $newdata HTTP::release unset newdata } } }
peace
/deb - Sean_Lagerholm_
Nimbostratus
Deb,
Wow, my first thought is, overkill, but compared to the C programming I assume the Apache proxy uses, it may be more efficient?
I'll try this irule out.
Thanks,
Sean - Sean_Lagerholm_
Nimbostratus
Deb,
Help! I'm getting an error on the first line :
line 1: [undefined procedure: class] [class ProxyPass { - Colin_Walker_12Historic F5 AccountThe class isn't actually part of the iRule.
The section that deb pasted is what would go into your config file directly, including the class and rule definition together.
If you are just inputing the iRule via the GUI, you would disregard the class, and add it seperately. So you'd exclude this section:class ProxyPass { space delimited row for each virtual to which rule will be applied vs_name backend_host_header backend_uri_prefix virtual1 inside_app1.company.com:7005 /newDir/otherDir virtual2 inside_app2.company.com:7006 /newDir/otherDir }
As well as the
portion, and the closing brace that matches it.rule ... {
Colin - Sean_Lagerholm_
Nimbostratus
Colin,
Thanks for the tip, I'm no longer getting irule syntax errors.
How do I define a class? - unRuleY_95363Historic F5 AccountThe above rule is not complete. You should search the forum or check out the Docs & Tips sections on replacing content. There are several good examples on methods to replace the content in a response.
- Deb_Allen_18Historic F5 AccountOk, I did a bit more reading & see that at least I need to move some of the response logic into an HTTP_RESPONSE_DATA event:
when HTTP_RESPONSE { if { 1 != $bypass }{ set length [HTTP::header Content-Length] HTTP::collect $length } } when HTTP_RESPONSE_DATA { if { 1 != $bypass }{ regsub -all $host_serverside$uri_prepend [HTTP::payload] $host_clientside newdata HTTP::payload replace 0 $length $newdata unset newdata } }
Thanks for the feedback, unRuleY, you've saved us some troubleshooting time, I'm sure.
So would HTTP::payload be a valid command in HTTP_RESPONSE event, since HTTP_RESPONSE is triggered before any payload is seen? (Syntax error might have clued me in to that one...)
thanks
/deb
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
