Skip to content

Commit 9383ec7

Browse files
committed
http/cookie: Use a minheap to optimise cookie cleanup
1 parent 66b34e8 commit 9383ec7

File tree

3 files changed

+27
-11
lines changed

3 files changed

+27
-11
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ This will automatically install run-time lua dependencies for you.
3434
- [basexx](https://github.com/aiq/basexx/) >= 0.2.0
3535
- [lpeg](http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html)
3636
- [lpeg_patterns](https://github.com/daurnimator/lpeg_patterns) >= 0.5
37+
- [binaryheap.lua](https://github.com/Tieske/binaryheap.lua)
3738
- [fifo](https://github.com/daurnimator/fifo.lua)
3839

3940
To use gzip compression you need **one** of:

http-scm-0.rockspec

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies = {
2020
"basexx >= 0.2.0";
2121
"lpeg";
2222
"lpeg_patterns >= 0.5";
23+
"binaryheap >= 0.3";
2324
"fifo";
2425
-- "psl"; -- Optional
2526
}

http/cookie.lua

+25-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ RFC 6265
44
]]
55

66
local http_patts = require "lpeg_patterns.http"
7+
local binaryheap = require "binaryheap"
78
local has_psl, psl = pcall(require, "psl")
89

910
local EOF = require "lpeg".P(-1)
@@ -96,6 +97,7 @@ local store_mt = {
9697
local function new_store()
9798
return setmetatable({
9899
domains = {};
100+
expiry_heap = binaryheap.minUnique();
99101
}, store_mt)
100102
end
101103

@@ -317,9 +319,11 @@ function store_methods:store(req_domain, req_path, req_is_http, req_is_secure, n
317319
cookie.creation_time = old_cookie.creation_time
318320

319321
-- Remove the old-cookie from the cookie store.
322+
self.expiry_heap:remove(old_cookie)
320323
end
321324

322325
path_cookies[cookie.name] = cookie
326+
self.expiry_heap:insert(cookie.expiry_time, cookie)
323327
end
324328

325329
return true
@@ -352,12 +356,20 @@ function store_methods:remove(domain, path, name)
352356
end
353357
if path == nil then
354358
-- Delete whole domain
359+
for _, path_cookies in pairs(domain_cookies) do
360+
for _, cookie in pairs(path_cookies) do
361+
self.expiry_heap:remove(cookie)
362+
end
363+
end
355364
self.domains[domain] = nil
356365
else
357366
local path_cookies = domain_cookies[path]
358367
if path_cookies then
359368
if name == nil then
360369
-- Delete all names at path
370+
for _, cookie in pairs(path_cookies) do
371+
self.expiry_heap:remove(cookie)
372+
end
361373
domain_cookies[path] = nil
362374
if next(domain_cookies) == nil then
363375
self.domains[domain] = nil
@@ -366,6 +378,7 @@ function store_methods:remove(domain, path, name)
366378
-- Delete singular cookie
367379
local cookie = path_cookies[name]
368380
if cookie then
381+
self.expiry_heap:remove(cookie)
369382
path_cookies[name] = nil
370383
if next(path_cookies) == nil then
371384
domain_cookies[path] = nil
@@ -463,19 +476,20 @@ end
463476

464477
function store_methods:clean()
465478
local now = self.time()
466-
for domain, domain_cookies in pairs(self.domains) do
467-
for path, path_cookies in pairs(domain_cookies) do
468-
for name, cookie in pairs(path_cookies) do
469-
if cookie.expiry_time < now then
470-
path_cookies[name] = nil
479+
while self.expiry_heap:peek().expiry_time < now do
480+
local cookie = self.expiry_heap:pop()
481+
local domain_cookies = self.domains[cookie.domain]
482+
if domain_cookies then
483+
local path_cookies = domain_cookies[cookie.path]
484+
if path_cookies then
485+
path_cookies[cookie.name] = nil
486+
if next(path_cookies) == nil then
487+
domain_cookies[cookie.path] = nil
488+
if next(domain_cookies) == nil then
489+
self.domains[cookie.domain] = nil
490+
end
471491
end
472492
end
473-
if next(path_cookies) == nil then
474-
domain_cookies[path] = nil
475-
end
476-
end
477-
if next(domain_cookies) == nil then
478-
self.domains[domain] = nil
479493
end
480494
end
481495
return true

0 commit comments

Comments
 (0)