limit_req.t 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/perl
  2. # (C) Maxim Dounin
  3. # Tests for nginx limit_req module.
  4. ###############################################################################
  5. use warnings;
  6. use strict;
  7. use Test::More;
  8. BEGIN { use FindBin; chdir($FindBin::Bin); }
  9. use lib 'lib';
  10. use Test::Nginx;
  11. ###############################################################################
  12. select STDERR; $| = 1;
  13. select STDOUT; $| = 1;
  14. my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(5);
  15. $t->write_file_expand('nginx.conf', <<'EOF');
  16. %%TEST_GLOBALS%%
  17. master_process off;
  18. daemon off;
  19. events {
  20. }
  21. http {
  22. %%TEST_GLOBALS_HTTP%%
  23. limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
  24. limit_req_zone $binary_remote_addr zone=long:10m rate=1r/s;
  25. limit_req_zone $binary_remote_addr zone=fast:10m rate=1000r/s;
  26. server {
  27. listen 127.0.0.1:8080;
  28. server_name localhost;
  29. location / {
  30. limit_req zone=one burst=1 nodelay;
  31. }
  32. location /long {
  33. limit_req zone=long burst=5;
  34. }
  35. location /fast {
  36. limit_req zone=fast burst=1;
  37. }
  38. }
  39. }
  40. EOF
  41. $t->write_file('test1.html', 'XtestX');
  42. $t->write_file('long.html', "1234567890\n" x (1 << 16));
  43. $t->write_file('fast.html', 'XtestX');
  44. $t->run();
  45. ###############################################################################
  46. like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'request');
  47. http_get('/test1.html');
  48. like(http_get('/test1.html'), qr/^HTTP\/1.. 503 /m, 'request rejected');
  49. http_get('/test1.html');
  50. http_get('/test1.html');
  51. # Second request will be delayed by limit_req, make sure it isn't truncated.
  52. # The bug only manifests itself if buffer will be filled, so sleep for a while
  53. # before reading response.
  54. my $l1 = length(http_get('/long.html'));
  55. my $l2 = length(http_get('/long.html', sleep => 1.1));
  56. is($l2, $l1, 'delayed big request not truncated');
  57. # make sure rejected requests are not counted, and access is again allowed
  58. # after 1/rate seconds
  59. like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'rejects not counted');
  60. # make sure negative excess values are handled properly
  61. http_get('/fast.html');
  62. select undef, undef, undef, 0.1;
  63. like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess');
  64. ###############################################################################