Niels Kristian
Niels Kristian

Reputation: 8865

redirect all root domain request to www. subdomain, keeping the URL intact

I want to redirect all traffic to root domain to the www. version while still keeping path/query string intact, how can I do that? I have setup a HAproxy config like follows:

frontend http
        bind *:80
        bind *:443

        acl has_www hdr_beg(host) -i www
        http-request redirect code 301 location http://www.%[hdr(host)]%[req.uri] unless has_www

However this one does the following: example.com/abc?page=1 => www.example.com, where I actually wan't it to do: example.com/abc?page=1 => www.example.com/abc?page=1 - what am I missing?

Upvotes: 0

Views: 2930

Answers (2)

dim
dim

Reputation: 179

A multi-domain solution for HAProxy 1.6 which redirects preserving the path and query parameters:

frontend 443
  http-request redirect prefix https://www.%[hdr(host)] code 301 unless { hdr_beg(host) -i www. }

Upvotes: 0

Louis Kriek
Louis Kriek

Reputation: 728

if you are using HAProxy 1.5 and up this should work for you

Single domain :

acl has_www hdr_beg(host) -i www
redirect prefix http://www.example.com code 301 unless has_www

Multiple domains: (dirty but works)

# match non www requests:
acl has_www      hdr_beg(host) -i www.

# add a header that says we need to redirect these type of requests (will explain later)
http-request add-header X-Host-Redirect yes unless has_www

# rule to identify newly added headers
acl www_redirect hdr_cnt(X-Host-Redirect) eq 1

# where the magic happens (insert www. in front of all marked requests)
reqirep ^Host:\ (.*)$ Host:\ www.\1 if www_redirect

# now hostname contains 'www.' so we can redirect to the same url
  redirect scheme http if www_redirect

The reason why we add a new header is because it seems that in HAProxy 1.5 and up, acls are being evalutated on each reference. so when you try to do this without the new header it does this :

#catch all domains that begin with 'www.'
acl has_www      hdr_beg(host) -i www.
#insert www. in front of all non www requests
reqirep ^Host:\ (.*)$ Host:\ www.\1 unless has_www
#now hostname contains 'www.' so when the next rule gets interpreted it does not match then fails  
#redirect to new url
redirect code 301 prefix / if has_www

hope this helps. I've tested this with 5 different domains on HAProxy 1.5 and it worked fine and kept the query strings intact on redirect

Upvotes: 1

Related Questions