Skip to content

Commit d9f1e49

Browse files
committed
http/hsts: Add a .max_items field
1 parent d136206 commit d9f1e49

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

doc/modules/http.hsts.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ Data structures useful for HSTS (HTTP Strict Transport Security)
77
Creates and returns a new HSTS store.
88

99

10+
### `hsts_store.max_items` <!-- --> {#http.hsts.max_items}
11+
12+
The maximum number of items allowed in the store.
13+
Decreasing this value will only prevent new items from being added, it will not remove old items.
14+
15+
Defaults to infinity (any number of items is allowed).
16+
17+
1018
### `hsts_store:clone()` <!-- --> {#http.hsts:clone}
1119

1220
Creates and returns a copy of a store.

http/hsts.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ local http_util = require "http.util"
88

99
local store_methods = {
1010
time = function() return os.time() end;
11+
max_items = (1e999);
1112
}
1213

1314
local store_mt = {
@@ -25,12 +26,14 @@ local function new_store()
2526
return setmetatable({
2627
domains = {};
2728
expiry_heap = binaryheap.minUnique();
29+
n_items = 0;
2830
}, store_mt)
2931
end
3032

3133
function store_methods:clone()
3234
local r = new_store()
3335
r.time = rawget(self, "time")
36+
r.n_items = rawget(self, "n_items")
3437
r.expiry_heap = binaryheap.minUnique()
3538
for host, item in pairs(self.domains) do
3639
r.domains[host] = item
@@ -63,6 +66,12 @@ function store_methods:store(host, directives)
6366
local old_item = self.domains[host]
6467
if old_item then
6568
self.expiry_heap:remove(old_item)
69+
else
70+
local n_items = self.n_items
71+
if n_items >= self.max_items then
72+
return false
73+
end
74+
self.n_items = n_items + 1
6675
end
6776
local expires = now + max_age
6877
local item = setmetatable({
@@ -81,6 +90,7 @@ function store_methods:remove(host)
8190
if item then
8291
self.expiry_heap:remove(item)
8392
self.domains[host] = nil
93+
self.n_items = self.n_items - 1
8494
end
8595
return true
8696
end
@@ -120,6 +130,7 @@ function store_methods:clean()
120130
while self:clean_due() < now do
121131
local item = self.expiry_heap:pop()
122132
self.domains[item.host] = nil
133+
self.n_items = self.n_items - 1
123134
end
124135
return true
125136
end

spec/hsts_spec.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,22 @@ describe("hsts module", function()
107107
assert.falsy(s:check("example.com"))
108108
assert.truthy(s:check("keep.me"))
109109
end)
110+
it("enforces .max_items", function()
111+
local s = http_hsts.new_store()
112+
s.max_items = 0
113+
assert.falsy(s:store("example.com", {
114+
["max-age"] = "100";
115+
}))
116+
s.max_items = 1
117+
assert.truthy(s:store("example.com", {
118+
["max-age"] = "100";
119+
}))
120+
assert.falsy(s:store("other.com", {
121+
["max-age"] = "100";
122+
}))
123+
s:remove("example.com", "/", "foo")
124+
assert.truthy(s:store("other.com", {
125+
["max-age"] = "100";
126+
}))
127+
end)
110128
end)

0 commit comments

Comments
 (0)