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


Reply via email to