Created a new config as an example. My existing config is huge, and hard to read (generated programtically).
In regards to the bug, it appears it was a bug. I was using 1.5-dev19. After upgrading to 1.5-dev22 it started behaving as expected. Below is the config I'm using to accomplish what I want. As mentioned, I'm basically rate limiting on a combination of the "X-Client-Id" header and the matching URL. And as you can see, it's quite ugly and complex to accomplish it :-( For example, the same X-Client-Id should be able to hit /foo/bar 3 times every 15 seconds, with only 1 open connection (the "0000" rules). It should be able to hit /asdf at 5 times every 15 seconds with 3 open connections (the "1111" rules). global log 127.0.0.1:514 local1 debug maxconn 4096 daemon stats socket /tmp/haproxy.sock level admin defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 timeout connect 200 timeout client 60000 timeout server 170000 option clitcpka option srvtcpka option abortonclose stats enable stats uri /haproxy/stats frontend f1 bind *:1500 option httpclose acl internal dst 127.0.0.2 acl have_request_id req.fhdr(X-Request-Id) -m found http-request set-header X-API-URL %[path] if !internal http-request add-header X-Request-Timestamp %Ts.%ms http-request set-header X-Request-Id %[req.fhdr(X-Request-Id)] if internal have_request_id http-request set-header X-Request-Id %{+X}o%pid-%rt if !internal || !have_request_id http-request set-header X-API-Host i-12345678 http-response set-header X-API-Host i-12345678 unique-id-format %{+X}o%pid-%rt log-format %ci:%cp\ %ft\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ %U/%B\ %ST\ %tsc\ %ID\ +\ %r acl rewrite-found req.hdr(X-Rewrite-ID,1) -m found acl 0000_path path_reg ^/foo/([^\ ?]*)$ acl 0000_method method GET http-request set-header X-Rewrite-Id 0000 if !rewrite-found 0000_path 0000_method acl 0000-rewrite req.hdr(X-Rewrite-Id) -m str 0000 http-request set-header X-Limit-Id 0000%[req.hdr(X-Client-Id)] if 0000-rewrite use_backend b1 if 0000-rewrite reqrep ^(GET)\ /foo/([^\ ?]*)([\ ?].*|$) \1\ /echo/bar/\2\3 if 0000-rewrite acl 1111_path path_reg ^/([^\ ?]*)$ acl 1111_method method GET http-request set-header X-Rewrite-Id 1111 if !rewrite-found 1111_path 1111_method acl 1111-rewrite req.hdr(X-Rewrite-Id) -m str 1111 http-request set-header X-Limit-Id 1111%[req.hdr(X-Client-Id)] if 1111-rewrite use_backend b1 if 1111-rewrite reqrep ^(GET)\ /([^\ ?]*)([\ ?].*|$) \1\ /echo/\2\3 if 1111-rewrite backend b1 stick-table type string len 12 size 1000 expire 1h store http_req_rate(15000),conn_cur tcp-request content track-sc2 req.hdr(X-Limit-ID) acl 0000-rewrite req.hdr(X-Rewrite-Id) -m str 0000 acl 0000_req_rate sc2_http_req_rate gt 3 acl 0000_conn_cur sc2_conn_cur gt 1 tcp-request content reject if 0000-rewrite 0000_req_rate tcp-request content reject if 0000-rewrite 0000_conn_cur acl 1111-rewrite req.hdr(X-Rewrite-Id) -m str 1111 acl 1111_req_rate sc2_http_req_rate gt 5 acl 1111_conn_cur sc2_conn_cur gt 3 tcp-request content reject if 1111-rewrite 1111_req_rate tcp-request content reject if 1111-rewrite 1111_conn_cur server s1 127.0.0.1:2700 server s2 127.0.0.1:2701 server s3 127.0.0.1:2702 -Patrick ------------------------------------------------------------------------ *From: *Baptiste <bed...@gmail.com> *Sent: * 2014-03-12 06:26:32 E *To: *Patrick Hemmer <hapr...@stormcloud9.net> *CC: *haproxy@formilux.org <haproxy@formilux.org> *Subject: *Re: tcp-request content track > It would be easier to help you if you share your configuration! > > Baptiste > > On Wed, Mar 12, 2014 at 1:36 AM, Patrick Hemmer <hapr...@stormcloud9.net> > wrote: >> 2 related questions: >> >> I'm trying to find a way to concat multiple samples to use in a stick table. >> Basically in my frontend I pattern match on the request path to determine >> which backend to send a request to. The client requests also have a client >> ID header. I want to rate limit based on a combination of this pattern that >> matched, and the client ID. Currently the way I do this is an "http-request >> set-header" rule that adds a new header combining a unique ID for the >> pattern that matched along with the client-ID header. Then in the backend I >> have a "tcp-requst content track-sc2" on that header. This works, but I'm >> wondering if there's a better way. >> >> >> Secondly, the above works, but when I do a "show table mybackend" on the >> stats socket, both the "conn_cur" and "use" counters never decrease. They >> seem to be acting as the total number of requests, not the number of active >> connections. Is this a bug, or am I misunderstanding something? >> >> >> -Patrick