diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-07-22 23:02:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-07-22 23:05:28 +0300 |
commit | 7cc646c790465f6975aafa52626b99d04ac2f62d (patch) | |
tree | 3ed4ed45093ce78750f228c737064f8327ac09c0 | |
parent | 88126134cd43e8da9ade49d18c757c6a41b777bc (diff) | |
download | vmod-tbf-7cc646c790465f6975aafa52626b99d04ac2f62d.tar.gz vmod-tbf-7cc646c790465f6975aafa52626b99d04ac2f62d.tar.bz2 |
New function "check"
* src/vmod_tbf.c (vmod_rate): Use %lu instead of %z
(vmod_check): New function.
* src/vmod_tbf.vcc (check): New function.
* tests/Makefile.am: Add new files.
* tests/test02.vtc: New file.
* tests/test03.vtc: New file.
* tests/time01.vtc: New file.
-rw-r--r-- | src/vmod_tbf.c | 71 | ||||
-rw-r--r-- | src/vmod_tbf.vcc | 1 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/test02.vtc | 47 | ||||
-rw-r--r-- | tests/test03.vtc | 71 | ||||
-rw-r--r-- | tests/time01.vtc | 23 |
6 files changed, 213 insertions, 2 deletions
diff --git a/src/vmod_tbf.c b/src/vmod_tbf.c index dab0987..02c26ec 100644 --- a/src/vmod_tbf.c +++ b/src/vmod_tbf.c | |||
@@ -337,8 +337,8 @@ vmod_rate(struct sess *sp, const char *key, int cost, double t, int burst_size) | |||
337 | if (cost <= bkt->tokens) { | 337 | if (cost <= bkt->tokens) { |
338 | res = 1; | 338 | res = 1; |
339 | bkt->tokens -= cost; | 339 | bkt->tokens -= cost; |
340 | debug(2, ("tbf_rate matched %s, tokens left %z", key, | 340 | debug(2, ("tbf_rate matched %s, tokens left %lu", key, |
341 | bkt->tokens)); | 341 | (unsigned long)bkt->tokens)); |
342 | } else { | 342 | } else { |
343 | res = 0; | 343 | res = 0; |
344 | debug(1, ("tbf_rate overlimit on %s", key)); | 344 | debug(1, ("tbf_rate overlimit on %s", key)); |
@@ -365,3 +365,70 @@ vmod_rate(struct sess *sp, const char *key, int cost, double t, int burst_size) | |||
365 | 365 | ||
366 | return res; | 366 | return res; |
367 | } | 367 | } |
368 | |||
369 | #define ISWS(c) ((c)==' '||(c)=='\t') | ||
370 | |||
371 | unsigned | ||
372 | vmod_check(struct sess *sp, const char *key, const char *spec) | ||
373 | { | ||
374 | double t, v, n; | ||
375 | char *p; | ||
376 | #define SKIPWS(init) for (init; *spec && ISWS(*spec); spec++) | ||
377 | int burst; | ||
378 | |||
379 | errno = 0; | ||
380 | v = strtod(spec, &p); | ||
381 | if (errno || v < 0) { | ||
382 | syslog(LOG_DAEMON|LOG_ERR, "bad rate: %s", spec); | ||
383 | return false; | ||
384 | } | ||
385 | SKIPWS(spec = p); | ||
386 | if (strncmp(spec, "req", 3)) { | ||
387 | syslog(LOG_DAEMON|LOG_ERR, | ||
388 | "bad rate: expected \"req\", but found \"%s\"", spec); | ||
389 | return false; | ||
390 | } | ||
391 | SKIPWS(spec += 3); | ||
392 | if (*spec != '/') { | ||
393 | syslog(LOG_DAEMON|LOG_ERR, | ||
394 | "bad rate: expected \"/\", but found \"%c\"", *spec); | ||
395 | return false; | ||
396 | } | ||
397 | SKIPWS(++spec); | ||
398 | if (*spec >= '0' && *spec <= '9') { | ||
399 | errno = 0; | ||
400 | n = strtod(spec, &p); | ||
401 | if (errno || n < 0) { | ||
402 | syslog(LOG_DAEMON|LOG_ERR, "bad interval: %s", spec); | ||
403 | return false; | ||
404 | } | ||
405 | spec = p; | ||
406 | } else | ||
407 | n = 1; | ||
408 | SKIPWS(); | ||
409 | |||
410 | switch (*spec) { | ||
411 | case 0: | ||
412 | case 's': | ||
413 | break; | ||
414 | case 'd': | ||
415 | n *= 24; | ||
416 | case 'h': | ||
417 | n *= 60; | ||
418 | case 'm': | ||
419 | n *= 60; | ||
420 | break; | ||
421 | default: | ||
422 | syslog(LOG_DAEMON|LOG_ERR, "invalid interval specifier: %s", | ||
423 | spec); | ||
424 | return false; | ||
425 | } | ||
426 | |||
427 | SKIPWS(++spec); | ||
428 | |||
429 | if (*spec) | ||
430 | syslog(LOG_DAEMON|LOG_WARNING, "garbage after rate spec: %s", | ||
431 | spec); | ||
432 | |||
433 | return vmod_rate(sp, key, 1, n/v, v/n+1); | ||
434 | } | ||
diff --git a/src/vmod_tbf.vcc b/src/vmod_tbf.vcc index babca68..637c4f8 100644 --- a/src/vmod_tbf.vcc +++ b/src/vmod_tbf.vcc | |||
@@ -4,6 +4,7 @@ Function VOID open(STRING, STRING) | |||
4 | Function VOID close() | 4 | Function VOID close() |
5 | Function VOID sync() | 5 | Function VOID sync() |
6 | Function BOOL rate(STRING, INT, DURATION, INT) | 6 | Function BOOL rate(STRING, INT, DURATION, INT) |
7 | Function BOOL check(STRING, STRING) | ||
7 | Function REAL getla(INT) | 8 | Function REAL getla(INT) |
8 | Function INT systime() | 9 | Function INT systime() |
9 | Function STRING strftime(STRING, INT) | 10 | Function STRING strftime(STRING, INT) |
diff --git a/tests/Makefile.am b/tests/Makefile.am index 5826201..383f18a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am | |||
@@ -1,6 +1,8 @@ | |||
1 | VMOD_TESTS = \ | 1 | VMOD_TESTS = \ |
2 | test00.vtc\ | 2 | test00.vtc\ |
3 | test01.vtc\ | 3 | test01.vtc\ |
4 | test02.vtc\ | ||
5 | test03.vtc\ | ||
4 | time00.vtc | 6 | time00.vtc |
5 | 7 | ||
6 | EXTRA_DIST=$(VMOD_TESTS) | 8 | EXTRA_DIST=$(VMOD_TESTS) |
diff --git a/tests/test02.vtc b/tests/test02.vtc new file mode 100644 index 0000000..b957181 --- /dev/null +++ b/tests/test02.vtc | |||
@@ -0,0 +1,47 @@ | |||
1 | varnishtest "Test tbf overlimit" | ||
2 | |||
3 | server s1 { | ||
4 | rxreq | ||
5 | txresp | ||
6 | } -start | ||
7 | |||
8 | varnish v1 -vcl+backend { | ||
9 | import tbf from "${vmod_topbuild}/src/.libs/libvmod_tbf.so"; | ||
10 | sub vcl_init { | ||
11 | tbf.open("${vmod_topbuild}/tests/tbf.db", "truncate"); | ||
12 | } | ||
13 | sub vcl_fini { | ||
14 | tbf.close(); | ||
15 | } | ||
16 | sub vcl_recv { | ||
17 | if (!tbf.check("url:"+req.url, "4 req/s")) { | ||
18 | error 420 "Overlimit"; | ||
19 | } | ||
20 | return (lookup); | ||
21 | } | ||
22 | } -start | ||
23 | |||
24 | client c1 { | ||
25 | txreq -url "/" | ||
26 | rxresp | ||
27 | expect resp.status == 200 | ||
28 | txreq -url "/" | ||
29 | rxresp | ||
30 | expect resp.status == 200 | ||
31 | txreq -url "/" | ||
32 | rxresp | ||
33 | expect resp.status == 200 | ||
34 | txreq -url "/" | ||
35 | rxresp | ||
36 | expect resp.status == 200 | ||
37 | txreq -url "/" | ||
38 | rxresp | ||
39 | expect resp.status == 200 | ||
40 | txreq -url "/" | ||
41 | rxresp | ||
42 | expect resp.status == 420 | ||
43 | } | ||
44 | |||
45 | client c1 -run | ||
46 | |||
47 | |||
diff --git a/tests/test03.vtc b/tests/test03.vtc new file mode 100644 index 0000000..5ffba9a --- /dev/null +++ b/tests/test03.vtc | |||
@@ -0,0 +1,71 @@ | |||
1 | varnishtest "Test tbf flow" | ||
2 | |||
3 | server s1 { | ||
4 | rxreq | ||
5 | txresp | ||
6 | } -start | ||
7 | |||
8 | varnish v1 -vcl+backend { | ||
9 | import tbf from "${vmod_topbuild}/src/.libs/libvmod_tbf.so"; | ||
10 | sub vcl_init { | ||
11 | tbf.open("${vmod_topbuild}/tests/tbf.db", "trunc"); | ||
12 | } | ||
13 | sub vcl_fini { | ||
14 | tbf.close(); | ||
15 | } | ||
16 | sub vcl_deliver { | ||
17 | set resp.http.result = tbf.check("url:"+req.url, "4req/s"); | ||
18 | } | ||
19 | } -start | ||
20 | |||
21 | client c1 { | ||
22 | txreq -url "/" | ||
23 | rxresp | ||
24 | expect resp.http.result == true | ||
25 | |||
26 | txreq -url "/" | ||
27 | rxresp | ||
28 | expect resp.http.result == true | ||
29 | |||
30 | txreq -url "/" | ||
31 | rxresp | ||
32 | expect resp.http.result == true | ||
33 | |||
34 | txreq -url "/" | ||
35 | rxresp | ||
36 | expect resp.http.result == true | ||
37 | |||
38 | txreq -url "/" | ||
39 | rxresp | ||
40 | expect resp.http.result == true | ||
41 | |||
42 | txreq -url "/" | ||
43 | rxresp | ||
44 | expect resp.http.result == false | ||
45 | |||
46 | delay 1.0 | ||
47 | |||
48 | txreq -url "/" | ||
49 | rxresp | ||
50 | expect resp.http.result == true | ||
51 | |||
52 | txreq -url "/" | ||
53 | rxresp | ||
54 | expect resp.http.result == true | ||
55 | |||
56 | txreq -url "/" | ||
57 | rxresp | ||
58 | expect resp.http.result == true | ||
59 | |||
60 | txreq -url "/" | ||
61 | rxresp | ||
62 | expect resp.http.result == true | ||
63 | |||
64 | txreq -url "/" | ||
65 | rxresp | ||
66 | expect resp.http.result == false | ||
67 | } | ||
68 | |||
69 | client c1 -run | ||
70 | |||
71 | |||
diff --git a/tests/time01.vtc b/tests/time01.vtc new file mode 100644 index 0000000..2325f4c --- /dev/null +++ b/tests/time01.vtc | |||
@@ -0,0 +1,23 @@ | |||