util/throttle.lua
author Jonas Schäfer <jonas@wielicki.name>
Mon, 10 Jan 2022 18:23:54 +0100
branch0.11
changeset 12185 783056b4e448
parent 8558 4f0f5b49bb03
child 12979 d10957394a3c
permissions -rw-r--r--
util.xml: Do not allow doctypes, comments or processing instructions Yes. This is as bad as it sounds. CVE pending. In Prosody itself, this only affects mod_websocket, which uses util.xml to parse the <open/> frame, thus allowing unauthenticated remote DoS using Billion Laughs. However, third-party modules using util.xml may also be affected by this. This commit installs handlers which disallow the use of doctype declarations and processing instructions without any escape hatch. It, by default, also introduces such a handler for comments, however, there is a way to enable comments nontheless. This is because util.xml is used to parse human-facing data, where comments are generally a desirable feature, and also because comments are generally harmless.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
7991
dc758422d896 util.statistics,statsd,throttle,timer: Replace dependency on LuaSockect with util.time for precision time
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
     2
local gettime = require "util.time".now
4466
28e0bf9cf0f5 util.throttle: Import setmetatable
Matthew Wild <mwild1@gmail.com>
parents: 4362
diff changeset
     3
local setmetatable = setmetatable;
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 4952
diff changeset
     5
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8275
diff changeset
     6
-- luacheck: std none
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local throttle = {};
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
local throttle_mt = { __index = throttle };
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
function throttle:update()
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
	local newt = gettime();
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	local elapsed = newt - self.t;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
	self.t = newt;
8248
9499db96c032 util.throttle: Fix initial time setting (double accounting the first time) and fractional balance updates (0.1*10 was not the same as 1*1)
Waqas Hussain <waqas20@gmail.com>
parents: 7991
diff changeset
    15
	local balance = (self.rate * elapsed) + self.balance;
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	if balance > self.max then
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
		self.balance = self.max;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	else
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
		self.balance = balance;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
	return self.balance;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
function throttle:peek(cost)
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
	cost = cost or 1;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	return self.balance >= cost or self:update() >= cost;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
function throttle:poll(cost, split)
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
	if self:peek(cost) then
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
		self.balance = self.balance - cost;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		return true;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	else
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
		local balance = self.balance;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
		if split then
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
			self.balance = 0;
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
		end
4467
fc8a22936b3c util.throttle: Fix 'outstanding' return value
Matthew Wild <mwild1@gmail.com>
parents: 4466
diff changeset
    38
		return false, balance, (cost-balance);
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
	end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 4952
diff changeset
    42
local function create(max, period)
8248
9499db96c032 util.throttle: Fix initial time setting (double accounting the first time) and fractional balance updates (0.1*10 was not the same as 1*1)
Waqas Hussain <waqas20@gmail.com>
parents: 7991
diff changeset
    43
	return setmetatable({ rate = max / period, max = max, t = gettime(), balance = max }, throttle_mt);
4362
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
end
851885cb332d util.throttle: Generic module by waqas to limit something over some time
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 4952
diff changeset
    46
return {
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 4952
diff changeset
    47
	create = create;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 4952
diff changeset
    48
};