Hi Cyril,
On Fri, Oct 25, 2013 at 12:05:44AM +0200, Cyril Bonté wrote:
> Hi all,
>
> Le 24/10/2013 00:36, Przemys?aw Hejman a écrit :
> >Hi,
> >
> >This does not seem to be working - I've also examined the table with
> >socat - It doesn't catch anything. Artef several requests through telnet
> >I still get:
> >
> >echo "show table" | socat unix:/tmp/haproxy.stats -
> ># table: app, type: string, size:204800, used:0
>
> I played with a similar configuration, and simplified it :
> global
> stats socket /tmp/haproxy.sock
>
> listen app :9000
> mode http
> option http-server-close
> stick-table type integer size 200k expire 3m store http_req_cnt
> tcp-request content track-sc0 urlp(SID,?)
> tcp-request content reject if { sc0_http_req_cnt gt 2 }
> server web01 127.0.0.1:80
>
> What happens with this configuration is that the entry is randomly
> created/updated, depending on timings. Sometimes it works, sometimes not.
>
> As urlp is a layer7 fetching sample, I assumed that the configuration
> required to specify "tcp-request inspect-delay", so I added :
> tcp-request inspect-delay 10s
>
> It wasn't better. It appears that the "urlp" fetch is processed too
> early and doens't care about the inspect delay.
> As a quick test, I modified the tcp_inspect_request() function.
> After this call (src/proto_tcp.c:950) :
> key = stktable_fetch_key(t, s->be, s, &s->txn,
> SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->act_prm.trk_ctr.expr);
>
> I added a condition :
> if (!key && !partial) {
> return 0;
> }
>
> It worked as expected:
>
> Init step :
> # table: app, type: integer, size:204800, used:0
>
> $ curl "localhost:9000/?SID=1"
> OK
>
> # table: app, type: integer, size:204800, used:1
> 0xc50fa4: key=1 use=0 exp=159420 http_req_cnt=1
>
> $ curl "localhost:9000/?SID=1"
> OK
>
> # table: app, type: integer, size:204800, used:1
> 0xc50fa4: key=1 use=0 exp=177602 http_req_cnt=2
>
> $ curl "localhost:9000/?SID=1"
> OK
>
> # table: app, type: integer, size:204800, used:1
> 0xc50fa4: key=1 use=0 exp=155563 http_req_cnt=3
>
> $ curl "localhost:9000/?SID=1"
> curl: (52) Empty reply from server
>
> This is not the right way to fix this, but maybe it can help Willy or
> someone at Exceliance to find one.
Good analysis. Indeed, "tcp-request track-sc*" does not wait for
anything (eg: for connection we must not wait). It is documented
as tracking only what is found. The proper method to wait for
contents if needed is to rely on a condition for the track rule
to take action :
listen app :9000
mode http
option http-server-close
stick-table type integer size 200k expire 3m store http_req_cnt
tcp-request inspect-delay 10s
tcp-request content reject unless HTTP
tcp-request content track-sc0 urlp(SID,?)
tcp-request content reject if { sc0_http_req_cnt gt 2 }
server web01 127.0.0.1:80
This "tcp-request content reject unless HTTP" will block until there
is a valid HTTP request in the buffer, or will reject an invalid
request. Alternatively, the following method will just apply the
condition to the first rule :
tcp-request inspect-delay 10s
tcp-request content track-sc0 urlp(SID,?) if HTTP
tcp-request content reject if { sc0_http_req_cnt gt 2 }
But I tend not to like it much because if you comment out the first
line while debugging, this may have side effects on other lines
below.
Best regards,
Willy