[Solved] Reversing http-request set-path


#1

We have a lot of projects with subdomains, so we set up haproxy to rewrite the path to match the subdomain and we have a CNAME for each project to projects.example.com:

listen projects_example_com
  bind ip_address:443 ssl crt /etc/haproxy/ssl/star_example_com.pem
  bind ip_address:80 
  mode http
  acl is_root var(req.rewrite_project) projects
  http-request set-var(req.rewrite_project) req.hdr(host),lower,regsub(\.example\.com$,) if { hdr_end(host) -i .example.com }
  http-request set-path /projects/%[var(req.rewrite_project)]%[path] if { var(req.rewrite_project) -m found }
  use_backend projects_default      if is_root
  use_backend projects_backend-ssl  if  { ssl_fc }
  use_backend projects_backend      if !{ ssl_fc }

backend projects_backend
  mode http
  server server1 172.24.0.33:8034 check
  server server2 172.24.0.34:8034 check
  server server3 172.24.0.41:8034 check

backend projects_backend-ssl
  mode http
  server server1 172.24.0.33:8434 check ssl verify none
  server server2 172.24.0.34:8434 check ssl verify none
  server server3 172.24.0.41:8434 check ssl verify none

backend projects_default
  mode http
  errorfile 503 /etc/haproxy/errors/projects.html.http

This works great except when you go to http://project2.example.com/folder and the backend Apache server tries to add the missing trailing slash by redirecting to http://project2.example.com/projects/project2/folder/, which then results in the new request for a folder that doesn’t exist, /projects/project2/projects/project2/folder/. Is there any way to get HAProxy to filter the returned URL to remove the extra /projects/project2?


#2

We managed to fix it like this:

listen projects_example_com
bind ip_address:443 ssl crt /etc/haproxy/ssl/star_example_com.pem
bind ip_address:80 
mode http
acl is_root var(req.rewrite_project) projects
http-request set-var(req.rewrite_project) req.hdr(host),lower,regsub(\.example\.com$,) if { hdr_end(host) -i  .example.com }
http-request set-path /projects/%[var(req.rewrite_project)]%[path] if { var(req.rewrite_project) -m found }
http-response replace-header Location (http|https)://([^/]*)/projects/([^/]*)/(.*)$ \1://\2/\4
use_backend projects_default      if is_root
use_backend projects_backend-ssl  if  { ssl_fc }
use_backend projects_backend      if !{ ssl_fc }