patg.net

home

HAProxy Tip

04 Aug 2017

Question: how do I have HAProxy redirect to another site and preserve the full URL?

I’ve been thinking: sometimes I feel that in order to post to my blog, it has to be significant. This runs contrary to the whole idea of “release early, release often” ideal in terms of documentation. Why not just post findings when they’re fresh in my mind? Here goes.

Today, I had a client who needed one site redirect another site and retain the full URL on the web front-end, which uses HAProxy. The existing redirects would do this for other sites, but would redirect to the front page and if whatever the full URL was that was acccessed was lost.

It was a pretty simple problem to solve, but not a lot of examples out there that were more complex.

First things first

When you test front-end proxy changes, disable your browswer’s cache! In Chrome, this is done with Dev tools->Network->check “Disable cache”. Other browswers can also have their cache disabled. Yes, I know, that seems obvious, but shift reload doesn’t work well nor is convenient when you cut-n-paste a URL from some other application or email to test your changes or have to explicitely clear it.

Also, have a test proxy that you spin up to make changes on and use /etc/hosts to have it respond as the front-end web proxy.

Original rules in HAProxy

The original rule went to a subdirectory on the main site, but this needed to be changed to have it go to a completely different site

acl is_somesite hdr(host) -i somesite.com
redirect code 301 location http://www.mainsite.com/somesite/ if is_somesite

It now needed instead to go from http://somesite.com/path?query_string to http://anothersite.com/path?query_string. The former rule didn’t work as:

redirect code 301 location http://www.anothersite.com if is_somesite

And would obviously go, regardless of the full URI, to http://www.anothersite.com

After searching, reading the manual, and specifically for the version being used, this did the trick:

acl is_somesite hdr_end(host) -i somesite.com
http-request redirect code 301 location http://www.anothersite.com%[capture.req.uri] if is_somesite

Note the use of hdr_end(host). The reason for this is it takes care of any subdomain and the main domain. Also, %[capture.req.uri] is the real magic for ensuring the full URL is carried over.

For the most recent version of HAProxy (7.0), it would be req.uri versus capture.req.uri

Summary

So, there it is. Hopefully this will help others save time.

More on redirection with HAProxy

comments powered by Disqus