diff --git a/limit_conn.t b/limit_conn.t index 7149919a..1d077d59 100644 --- a/limit_conn.t +++ b/limit_conn.t @@ -23,7 +23,7 @@ select STDOUT; $| = 1; my $t = Test::Nginx->new()->has(qw/http proxy limit_conn limit_req/); -$t->write_file_expand('nginx.conf', <<'EOF')->plan(8); +$t->write_file_expand('nginx.conf', <<'EOF')->plan(10); %%TEST_GLOBALS%% @@ -40,6 +40,7 @@ http { limit_conn_zone $binary_remote_addr zone=zone:1m; limit_conn_zone $binary_remote_addr zone=zone2:1m; limit_conn_zone $binary_remote_addr zone=custom:1m; + limit_conn_zone $http_x_key zone=key:1m; server { listen 127.0.0.1:8081; @@ -48,6 +49,10 @@ http { location /w { limit_req zone=req burst=10; } + + location /empty { + return 204; + } } server { @@ -77,6 +82,11 @@ http { limit_conn_status 501; limit_conn custom 1; } + + location /key { + proxy_pass http://127.0.0.1:8081/empty; + limit_conn key 10; + } } } @@ -115,4 +125,28 @@ $s = http_get('/w', start => 1); like(http_get('/unlim'), qr/404 Not Found/, 'unlimited passed'); like(http_get('/'), qr/503 Service/, 'limited rejected'); +# a key within the length limit is not rejected, while an overlong key is +# rejected instead of silently skipping the limit + +unlike(http_key('/key', 'short'), qr/^HTTP\/1.. 503 /, 'key passed'); + +TODO: { +local $TODO = 'not yet'; + +like(http_key('/key', 'x' x 300), qr/^HTTP\/1.. 503 /, 'overlong key rejected'); + +} + +############################################################################### + +sub http_key { + my ($uri, $key) = @_; + return http(<new()->has(qw/http limit_req/)->plan(6); +my $t = Test::Nginx->new()->has(qw/http limit_req/)->plan(8); $t->write_file_expand('nginx.conf', <<'EOF'); @@ -38,6 +38,9 @@ http { limit_req_zone $binary_remote_addr zone=one:1m rate=2r/s; limit_req_zone $binary_remote_addr zone=long:1m rate=2r/s; limit_req_zone $binary_remote_addr zone=fast:1m rate=1000r/s; + limit_req_zone $http_x_key zone=key:1m rate=1000r/s; + + large_client_header_buffers 4 128k; server { listen 127.0.0.1:8080; @@ -45,6 +48,9 @@ http { location / { limit_req zone=one burst=1 nodelay; } + location /keyreq.html { + limit_req zone=key burst=100; + } location /status { limit_req zone=one burst=1 nodelay; @@ -64,6 +70,7 @@ EOF $t->write_file('test1.html', 'XtestX'); $t->write_file('long.html', "1234567890\n" x (1 << 16)); $t->write_file('fast.html', 'XtestX'); +$t->write_file('keyreq.html', 'XtestX'); $t->run(); ############################################################################### @@ -94,4 +101,29 @@ http_get('/fast.html'); select undef, undef, undef, 0.1; like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess'); +# a key within the length limit is not rejected, while an overlong key is +# rejected instead of silently skipping the limit + +unlike(http_key('/keyreq.html', 'short'), qr/^HTTP\/1.. 503 /m, 'key passed'); + +TODO: { +local $TODO = 'not yet'; + +like(http_key('/keyreq.html', 'x' x 65600), qr/^HTTP\/1.. 503 /m, + 'overlong key rejected'); + +} + +############################################################################### + +sub http_key { + my ($uri, $key) = @_; + return http(<new()->has(qw/http stream stream_limit_conn/) - ->plan(8)->write_file_expand('nginx.conf', <<'EOF'); + ->plan(9)->write_file_expand('nginx.conf', <<'EOF'); %%TEST_GLOBALS%% @@ -38,6 +38,9 @@ stream { limit_conn_zone $binary_remote_addr zone=zone:1m; limit_conn_zone $binary_remote_addr zone=zone2:1m; + # a key that always exceeds the 255-byte storable length + limit_conn_zone "$binary_remote_addr aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" zone=longkey:1m; + server { listen 127.0.0.1:8080; proxy_pass 127.0.0.1:8084; @@ -67,6 +70,12 @@ stream { proxy_pass 127.0.0.1:8080; limit_conn zone 1; } + + server { + listen 127.0.0.1:8086; + proxy_pass 127.0.0.1:8084; + limit_conn longkey 1; + } } http { @@ -111,6 +120,15 @@ EOF like(get('127.0.0.1:' . port(8082)), qr/200 OK/, 'passed proxy'); is(get('127.0.0.1:' . port(8083)), undef, 'rejected proxy'); +# an overlong key is rejected instead of silently skipping the limit + +TODO: { +local $TODO = 'not yet'; + +is(get('127.0.0.1:' . port(8086)), undef, 'overlong key rejected'); + +} + ############################################################################### sub get {