title: HAProxy http-request redirect a specific path to another path
body: <p>I am quite familiar with the HTTP protocol and a little bit of HAProxy, but I have never really messed up with URL rewrites and redirects before. Now, I have 2 "simple" HTTP redirect requirements which I have been having a hard time figuring out.</p>
  
  <ol>
  <li><code>https://appserver.example.com</code> should be redirected to <code>https://appserver.example.com/myapp/webapp/?auth=saml</code> to point the user to <code>saml</code> login page.</li>
  <li><code>https://appserver.example.com/?auth=standard</code> should be redirected to <code>https://appserver.example.com/myapp/webapp/?auth=standard</code></li>
  </ol>
  
  <p>Requirement 1 works fine:</p>
  
  <pre><code>myuser:~ myuser$ curl -I https://appserver.example.com
  HTTP/1.1 301 Moved Permanently
  Content-length: 0
  Location: https://appserver.example.com/myapp/webapp/?auth=saml
  Connection: close
  
  myuser:~ myuser$ 
  </code></pre>
  
  <p>But I am having a hard time on how to implement #2. The key to this, as I thought, is to add an <code>acl</code>, then another <code>http-request redirect prefix</code> line when the <code>acl</code> is matched. </p>
  
  <pre><code>acl is_auth_std path /?auth=standard
  http-request redirect prefix /myapp/webapp/?auth=standard code 301 if is_auth_std
  </code></pre>
  
  <p>But apparently this is not enough. <code>/?auth=standard</code> still redirects to the supposed root URL:</p>
  
  <pre><code>myuser:~ myuser$ curl -I https://appserver.example.com/?auth=standard
  HTTP/1.1 301 Moved Permanently
  Content-length: 0
  Location: https://appserver.example.com/myapp/webapp/?auth=saml
  Connection: close
  
  myuser:~ myuser$
  </code></pre>
  
  <p>These are the relevant sections of my <code>haproxy.cfg</code> file:</p>
  
  <pre><code>frontend myapp443-in
      mode http
      bind *:443 ssl crt /etc/haproxy/ssl/myapp.pem
      default_backend myapp443-out
      option forwardfor
  
      timeout client          60m
      timeout http-keep-alive 10s
      timeout http-request    5s
      timeout tarpit          60s
  
      acl is_websocket path_beg /myapp/webapp/
      acl is_websocket hdr(Upgrade) -i WebSocket
      acl is_websocket hdr_beg(Host) -i ws
  
      acl is_root path /
  
      capture request  header Host len 64
  
      http-request redirect scheme https code 301 if !{ ssl_fc }
      http-request redirect code 301 location https://%[hdr(host)]/myapp/webapp/?auth=saml if is_root
      acl is_auth_std path /?auth=standard
      http-request redirect prefix /myapp/webapp/?auth=standard code 301 if is_auth_std
  
  backend myapp443-out
      cookie SRVID insert indirect nocache maxidle 30m maxlife 1h
      option forwardfor
      balance leastconn
  
      option ssl-hello-chk
  
      option httpchk GET /myapp/webapp/img/favicon.ico
      http-check expect status 200
      default-server inter 1s downinter 3s rise 15 fall 15
      timeout check 1s
  
      timeout server          60s
      timeout tunnel        3600s
      timeout queue           30s
      timeout connect          5s
  
      http-request add-header X-Forwarded-Proto https if { ssl_fc }
  
      redirect scheme https if !{ ssl_fc }
  
      http-response add-header Strict-Transport-Security max-age=31536000;\ includeSubdomains
      http-response add-header X-Content-Type-Options nosniff
      http-response add-header X-XSS-Protection 1;\ mode=block
      http-response add-header Referrer-Policy no-referrer
      http-response add-header Feature-Policy accelerometer\ 'none';\ ambient-light-sensor\ 'none';\ autoplay\ 'none';\ camera\ 'none';\ display-capture\ 'none';\ document-domain\ 'none';\ fullscreen\ 'none';\ execution-while-not-rendered\ 'none';\ execution-while-out-of-viewport\ 'none';\ gyroscope\ 'none';\ magnetometer\ 'none';\ microphone\ 'none';\ midi\ 'none';\ payment\ 'none';\ picture-in-picture\ 'none';\ publickey-credentials\ 'none';\ sync-xhr\ 'none';\ usb\ 'none';\ wake-lock\ 'none'
  
      server appserver-01 appserver-01:8443 weight 5 check ssl verify none cookie s1
      server appserver-02 appserver-02:8443 weight 5 check ssl verify none cookie s1
  </code></pre>
  
  <p>Any ideas what I am missing?</p>
  
  <p>Thanks.</p>