Removing "www."; what (expression) replaces the scheme?

TLDR; text in bold.

I’m attempting to come up with something to accept traffic on www. and redirect it the naked domain (so it’s clear it’s not used).

frontend port[80|443] from httpees
  ...
  http-request set-var(txn.txnhost) hdr(host)
  acl nowwwredir var(txn.txnhost) -m beg -i www.
  http-request redirect location http://%[req.hdr(Host),lower,regsub(www\.,,i)] code 30[1|2|3] if nowwwredir
  ...

…or:

frontend port[80|443] from httpees
  ...
  http-request set-var(txn.txnhost) hdr(host)
  http-request redirect location http://%[req.hdr(host),lower,regsub(www\.,,i)] code 30[1|2|3] if { var(txn.txnhost) -m beg -i www. }
  ...

I’m not completely sure if the unnamed ACL is correct. Anyway, while I have worked out everything to be as generic as possible and do have separate http://** and https:// frontends to infer the schemes, I’d like to replace the target scheme with an expression too, if possible. What would this be?

I’m open to different methods or other advise. :slight_smile:



Sidenote

I considered the other redirects too but it quickly became confusing when the prefix keyword appeared because I’ve seen several definitions for location that are up there with the definition of URL vs URI (something I forget about while reading about it): 1. the URL from scheme to path, 2. the path, when it’s called a relative URL, 3. once again refers to the path both httpd’s and nginx’s documentation. Then comes prefix` which in most software I’ve encountered that asks for this, it refers to the beginning of the path for reverse-proxy-awareness but here it seems that this can be the whole URI up to the query part or nothing but rather some construct for cookie injection depending on how is it written and have seen examples where it can replace everything but can’t make sense of them. Finally there’s an option for scheme only but I think that would needs to be its own ACL.

**

e.g; for things like OCSP, root CA’s public key, non-DNS ACME, Profile Manager (initial contact), device provisioning, …

It’s not exactly clear what you are trying to achieve with regard to TLS. So I would assume that HTTP traffic should be redirected to HTTP, and HTTPS to HTTPS.

Thus the only rules you require is the following (you don’t need other variables):

acl should-redirect hdr(host) -m beg -i www.
http-request redirect location %[pathq] code 301 if should-redirect

If you always want to redirect to HTTPS (i.e. if either Host begins with www. or TLS is not present) then it should be:

acl should-redirect hdr(host) -m beg -i www.
acl should-redirect ssl_fc(),not -m bool
http-request redirect location https://%[hdr(host),lower,'regsub("^www\.",,i)']%[pathq] code 301 if should-redirect

(I’ve not tested these, and I might got some quoting wrong, but at least with regard to the 2.5 manual it should be OK.)

(In both cases pathq is important as it should retain the query, and url doesn’t work in case of HTTP/2 when it contains also the host.)

Got it. Always %[pathq]. I almost missed the answer email completely–sorry!

I see you are entering https:// in the string though, that’s what I want to replace–the other part (removing www. from the FQDN) I had it already:

I know it’s sort of pointless because I have different frontend for each type for traffic, but by the same logic I could’ve just as well used easier rules to remove the www. since I know the domains I’m hosting. I’d like to learn how to write the full substitution string in expressions; something like: http-request redirect location %[req.conn(scheme)]://%[req.hdr(host),lower,regsub(www.,i)] code 302 if { var(txn.txnhost) -m beg -i www. } but something not made up.

Thanks for answering, I’ll try not to forget the path since now on. I already save all of this in my notes–just in case. :slight_smile: