├── .gitignore ├── LICENSE ├── README.md ├── conf └── nginx.conf ├── lua └── test.lua └── resty └── iresty_limits.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | logs/* 43 | 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, YuanSheng Wang 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lua-resty-limits 2 | limit nginx request every seconds base on openresty 3 | 4 | # Use exmaple 5 | 6 | ```lua 7 | local limits = require("resty.iresty_limits") 8 | local limits = limits.new() 9 | 10 | -- the rate is 80bytes/seconds, you can input 80K(means 80KB/sec) too. 11 | limits:rate("80") 12 | 13 | -- 14 | ngx.say("check request is allowed: ", 15 | limits:reqs_per_range(ngx.var.binary_remote_addr, ngx.var.uri, 1, 2)) 16 | ``` 17 | 18 | provide by membphis@gmail.com 19 | 20 | if you have any question, please let me know. -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | #user nobody; 2 | worker_processes 1; 3 | 4 | error_log logs/error.log warn; 5 | #pid logs/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | 12 | http { 13 | # set search paths for pure Lua external libraries (';;' is the default path): 14 | lua_package_path '$prefix/?.lua;;'; 15 | 16 | lua_code_cache off; 17 | lua_shared_dict itesty_limit 10m; 18 | 19 | server { 20 | listen 8000; 21 | server_name localhost; 22 | 23 | location /test { 24 | access_by_lua_file lua/test.lua; 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /lua/test.lua: -------------------------------------------------------------------------------- 1 | local limits = require("resty.iresty_limits") 2 | local limits = limits.new() 3 | 4 | -- the rate is 80bytes/seconds, you can input 80K(means 80KB/sec) too. 5 | limits:rate("80") 6 | 7 | -- 8 | ngx.say("check request is allowed: ", 9 | limits:reqs_per_range(ngx.var.binary_remote_addr, ngx.var.uri, 1, 2)) -------------------------------------------------------------------------------- /resty/iresty_limits.lua: -------------------------------------------------------------------------------- 1 | local _M = { _VERSION = '1.0' } 2 | 3 | local mt = { __index = _M } 4 | 5 | function _M.new(self) 6 | local shared_memory = ngx.shared.itesty_limit 7 | return setmetatable({ memory = shared_memory }, mt) 8 | end 9 | 10 | function _M.reqs_per_range(self, zone, key, requests, range) 11 | range = range or 1 12 | local zone_key = zone .. ":" .. key .. ":" .. math.ceil (ngx.time()/range) 13 | self.memory:add(zone_key, 0, range) 14 | local cur_para = self.memory:incr(zone_key, 1) 15 | if cur_para > requests then 16 | return false 17 | end 18 | 19 | return true 20 | end 21 | 22 | function _M.rate( self, rate ) 23 | ngx.var.limit_rate = rate or "0" 24 | return 25 | end 26 | 27 | return _M 28 | --------------------------------------------------------------------------------