title: HAProxy 1.4: remove multiple slashes
body: <p>I want to remove multiple slashes with haproxy:</p>
  
  <pre><code>$ curl -I "http://www.host.com//some_path/sub_path/slug/"
  </code></pre>
  
  <p>and make it send a 301 response for SEO purposes:</p>
  
  <pre><code>HTTP/1.1 301 Moved Permanently
  Cache-Control: no-cache
  Content-length: 0
  Location: /some_path/subpath/slug/
  </code></pre>
  
  <p><strong>First</strong> approach: Create ACL -> replace slashes -> redirect</p>
  
  <pre><code>acl multiple-bars path_reg /{2,}
  reqrep ^([^\ :]*)\ /{2,}(.*)     \1\ /\2 if multiple-bars
  ...
  redirect prefix / code 301 if multiple-bars
  </code></pre>
  
  <p>The reqrep changes the URL so that "multiple-bars" is no more true. Therefore I got no 301 redirect</p>
  
  <pre><code>$ curl -I "http://www.host.com//some_path/sub_path/slug/"
  HTTP/1.1 200 OK
  domain=www.host.com
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  Content-Type: text/html; charset=UTF-8
  Date: Tue, 09 Jun 2015 18:16:36 GMT
  </code></pre>
  
  <p><strong>Second</strong> approach: Create a Custom Header and redirect if it finds the header</p>
  
  <pre><code>acl multiple-bars path_reg /{2,}
  reqadd X-HadMultipleBars if multiple-bars
  reqrep ^([^\ :]*)\ /{2,}(.*)     \1\ /\2 if multiple-bars
  ...
  redirect prefix / code 301 if { hdr_cnt(X-HadMultipleBars) 1 }
  </code></pre>
  
  <p>But HAProxy first processes reqrep rules and then reqadd. So:</p>
  
  <pre><code>[ec2-user@haproxy-stage-m3m-a haproxy]$ sudo service haproxy restart
  Stopping haproxy:                                          [  OK  ]
  Starting haproxy: [WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:87] : a 'reqrep' rule placed after a 'reqadd' rule will still be processed before.
  [WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:103] : a 'reqidel' rule placed after a 'reqadd' rule will still be processed before.
  [WARNING] 159/181957 (11430) : parsing [/etc/haproxy/haproxy.cfg:104] : a 'reqrep' rule placed after a 'reqadd' rule will still be processed before.
                                                             [  OK  ]
  </code></pre>
  
  <p>It won't redirect:</p>
  
  <pre><code>$ curl -I "http://www.host.com//some_path/sub_path/slug/"
  HTTP/1.1 200 OK
  domain=www.host.com
  Expires: Thu, 19 Nov 1981 08:52:00 GMT
  Content-Type: text/html; charset=UTF-8
  Date: Tue, 09 Jun 2015 18:16:36 GMT
  </code></pre>
  
  <p><strong>Third</strong> approach:</p>
  
  <pre><code>acl multiple-bars path_reg /{2,}
  reqrep ^([^\ :]*)\ /{2,}(.*)    \1\ /\2\nX-HadMultipleBars: if multiple-bars
  ...
  redirect prefix / code 301 if { hdr_cnt(X-HadMultipleBars) 1 }
  </code></pre>
  
  <p>I don't like this <em>hack</em>, it looks dirty, but it works: the <code>hdr_cnt</code> gets the value of 1.</p>
  
  <p>It works with multiple slashes:</p>
  
  <pre><code>$ curl -I "http://www.host.com/////some_path/sub_path/slug/"
  HTTP/1.1 301 Moved Permanently
  Cache-Control: no-cache
  Content-length: 0
  Location: /some_path/sub_path/slug/
  </code></pre>
  
  <p>But it doesn't work with <em>sub_path</em> multiple slashes:</p>
  
  <pre><code>$ curl -I "http://www.host.com//////some_path///sub_path////slug/////"
  HTTP/1.1 301 Moved Permanently
  Cache-Control: no-cache
  Content-length: 0
  Location: /some_path///sub_path////slug/////
  </code></pre>
  
  <p>I'm having trouble to make this regex somewhat recursive, but this code removes some 'random' slashes at each time:</p>
  
  <pre><code>http://www.host.com//////some_path///sub_path////slug/////
  301 -&gt; Location: /some_path///sub_path////slug/////
  301 -&gt; Location: /some_path//sub_path//slug///
  301 -&gt; Location: /some_path/sub_path/slug//
  301 -&gt; Location: /some_path/sub_path/slug/
  200!
  </code></pre>
  
  <p>I tried to use this regex which works at <a href="http://www.regexr.com/" rel="nofollow">http://www.regexr.com/</a> instead of backreferencing to <code>([^\ :]*)</code></p>
  
  <pre><code>#Parses Valid URL characters:
  ([!#$&amp;-.0-;=?-[\]_a-z~]|%[0-9a-fA-F]{2})+
  </code></pre>
  
  <p>but it doesn't work on HAProxy 1.4 :(
  Can someone give me some help here?</p>
  
  <p>Thanks!</p>