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

Reply via email to