Re: Automatic Redirect transformations using regex?

2019-01-22 Thread Bruno Henc

Hello Joao Guimaraes,


The following lines should accomplish what you described in your email:


    acl is_main_site hdr(Host) -i www.mysite.com mysite.com
    http-request set-var(req.scheme) str(https) if { ssl_fc }
    http-request set-var(req.scheme) str(http) if !{ ssl_fc }

    http-request redirect code 301 location 
%[var(req.scheme)]://%[req.hdr(Host),regsub(www.,,i),lower,field(2,'.')].mysite.com%[capture.req.uri] 
if !is_main_site



Explained line by line, the ACL is_main_site prevents a redirect loop 
(www.mysite.com redirected to mysite.www or some other terrible 
monstrosity often found when dealing with redirects). I highly recommend 
thoroughly testing any redirect before deploying to production, as 
redirect loops are quite nasty to debug.



The second and third line define a variable req.scheme that is used to 
redirect either to http or https versions of a site. If you're doing 
HTTPS only, you can drop these two lines and hardcode the following line 
to redirect directly to HTTPS:



    acl is_main_site hdr(Host) -i www.mysite.com mysite.com
    http-request redirect code 301 location 
https://%[req.hdr(Host),regsub(www.,,i),lower,field(2,'.')].mysite.com%[capture.req.uri] 
if !is_main_site


_Please note that set-var requires haproxy 1.7 or any later version.
_

Also, if you are not performing SSL termination on the HAProxy instance 
doing the redirect you will probably need to read a header value (most 
likely X-Forwarded-Proto) instead of using { ssl_fc } to correctly set 
the req.var variable ( alternatively, you can use the header value 
directly for e.g. X-Forwarded-Proto by starting the redirect with 
%[hdr(X-Forwarded_Proto)]:// ).



Finally, the redirect itself can be explained:

  http-request redirect code 301 location 
%[var(req.scheme)]://%[req.hdr(Host),regsub(www.,,i),lower,field(2,'.')].mysite.com%[capture.req.uri] 
if !is_main_site



As explained above, this part sets the HTTP scheme to either http;// or 
https://


This part strips the www. prefix (if present) from e.g. www.mysite.fr to 
leave only mysite.fr . The i flag in regsub means that a 
case-insensitive match is performed. If you need to match multiple 
patterns (e.g. pictures.mysite.fr, chain multiple regsub statements.


Lower simply turns everything lowercase.

Field does the magic in this redirect and splits the prepared header 
string by the separator '.' into a list (starting with index 1). We are 
only interested in the 2 part, that is, the TLD. Please note that any 
insanity with ccTLDs 
 
(mysite.co.uk), multilevel subdomains (my.pictures.mysite.fr) or similar 
won't work with this redirect. If you need a redirect with general 
support for those, I recommend using regirep. Alternatively, if you need 
to cover just one ccTLD, you can use regsub to replace .co.uk with .uk  
. Also, as Aleksandar Lazic mentioned in his reply, haproxy map files 
are also an option. Map files might be more pleasant that regirep if you 
need to handle something exotic.



capture.req.uri saves the whole URI (path + query_string) so if you 
accessed mysite.fr/cute.php?cat the redirect would go to 
fr.mysite.com/cute.php?cat . if you just used path, you would loose the 
?cat query parameter at the end.



Hope this helps, My apologies for the longer email but covering the 
general case of the problem requires mentioning the major caveats you 
might experience. Turns out, rewriting URLs is a non-trivial (and rather 
not-fun) exercise.


Let me know if you have any questions.

Best regards,

Bruno Henc


On 1/21/19 11:40 PM, Joao Guimaraes wrote:

Hi Haproxy team!

I've been trying to figure out how to perform automatic redirects 
based on source URL transformations.


*Basically I need the following redirect: *

mysite.*abc* redirected to *abc*.mysite.com .


Note that mysite.abc is not fixed, must apply to whatever abc wants to be.

*Other examples:*
*
*

mysite.fr  TO fr.mysite.com 
mysite.es  TO es.mysite.com 
mysite.us  TO us.mysite.com 
mysite.de  TO de.mysite.com 
mysite.uk  TO uk.mysite.com 


Thanks in advance!
Joao Guimaraes




Re: Automatic Redirect transformations using regex?

2019-01-22 Thread Aleksandar Lazic
Am 21.01.2019 um 23:40 schrieb Joao Guimaraes:
> Hi Haproxy team!
> 
> I've been trying to figure out how to perform automatic redirects based on
> source URL transformations. 
> 
> *Basically I need the following redirect: *
> 
> mysite.*abc* redirected to *abc*.mysite.com .

Maybe you can reuse the solution from reg-tests dir.

47 # redirect Host: example.org / subdomain.example.org
48 http-request redirect prefix
%[req.hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/h3.map)] code 301
if { hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/h3.map) -m found }

This solution uses a map for redirect.

http://git.haproxy.org/?p=haproxy-1.9.git;a=blob;f=reg-tests/http-rules/h3.vtc;h=55bb2687d3abe02ee74eca5283e50b039d6d162e;hb=HEAD#l47

> Note that mysite.abc is not fixed, must apply to whatever abc wants to be.
> 
> *Other examples:*
> *
> *
> 
> mysite.fr TO fr.mysite.com
> mysite.es TO es.mysite.com
> mysite.us TO us.mysite.com
> mysite.de TO de.mysite.com
> mysite.uk TO uk.mysite.com
> 
> 
> Thanks in advance!
> Joao Guimaraes

Best regards
Aleks



Automatic Redirect transformations using regex?

2019-01-21 Thread Joao Guimaraes
Hi Haproxy team!

I've been trying to figure out how to perform automatic redirects based on
source URL transformations.

*Basically I need the following redirect: *

mysite.*abc* redirected to *abc*.mysite.com.


Note that mysite.abc is not fixed, must apply to whatever abc wants to be.

*Other examples:*

mysite.fr TO fr.mysite.com
mysite.es TO es.mysite.com
mysite.us TO us.mysite.com
mysite.de TO de.mysite.com
mysite.uk TO uk.mysite.com


Thanks in advance!
Joao Guimaraes