HAProxy URL Rewrite gives 400 Bad Request and NOSRV

haproxyhttpregex

I am trying to rewrite part of a uri using reqrep.

haproxy.cfg (original)

global
  log 127.0.0.1 local2
  daemon
  maxconn 256
defaults
  mode http
  log global
  option httplog
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms

frontend haproxy_in
  bind *:8080

  default_backend myapp


backend myapp

  server app1 localhost:8123 check

When I do this, I see haproxy log what I expect. Note I am using a dummy python server with cannot handle POST, so the 501 is of no concern, just the fact that the request was routed is what I am looking for.

haproxy_in myapp/app1 0/0/0/1/5 501 379 - - ---- 0/0/0/0/0 0/0 "POST /please/rewrite/this/ HTTP/1.1

I also see my server log the following.

 "POST /please/rewrite/this/ HTTP/1.1" 501 -

haproxy.cdf (with reqrep)

global
  log 127.0.0.1 local2
  daemon
  maxconn 256
defaults
  mode http
  log global
  option httplog
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms

frontend haproxy_in
  bind *:8080

  default_backend myapp


backend myapp

  reqrep ^([^\ :]*\ /) "POST\ /test\ HTTP/1.1"

  server app1 localhost:8123 check

With the reqrep added, I get error messages from haproxy

haproxy_in myapp/<NOSRV> -1/-1/-1/-1/1 400 187 - - PR-- 0/0/0/0/3 0/0 "POST /please/rewrite/this/ HTTP/1.1"

Apparently my request is invalid? It looks like the request doesn't make it out of haproxy. How can I see what the request is rewritten to? I have tried several different reqrep commands with different regex, and all seem to give me the same error.

My haproxy version is 1.5.16.

Best Answer

reqrep takes three parameters <search> <string> <cond>.

<search>: is the URL, for example www.somedomain.com/please/rewrite/this/

<string>: is the replace string, for example /test

<cond>: is for any special conditions, ignore it for now.

In the example, the replace will do the following:

FROM: http://www.somedomain.com/please/rewrite/this/

TO: /test

The following will do the replacement:

reqrep http://www.somedomain.com/please/rewrite/this/ http://www.somedomain.com/test

If you want to replace ignoring the domain you need to set it with regex:

reqrep ^([^\ :]*)\/please/rewrite/this/ \1\/test

Related Topic