@@ -3,6 +3,7 @@ Data structures useful for HSTS (HTTP Strict Transport Security)
33HSTS is described in RFC 6797
44]]
55
6+ local binaryheap = require " binaryheap"
67local http_util = require " http.util"
78
89local store_methods = {
@@ -23,14 +24,17 @@ local store_item_mt = {
2324local function new_store ()
2425 return setmetatable ({
2526 domains = {};
27+ expiry_heap = binaryheap .minUnique ();
2628 }, store_mt )
2729end
2830
2931function store_methods :clone ()
3032 local r = new_store ()
3133 r .time = rawget (self , " time" )
34+ r .expiry_heap = binaryheap .minUnique ()
3235 for host , item in pairs (self .domains ) do
3336 r .domains [host ] = item
37+ r .expiry_heap :insert (item .expires , item )
3438 end
3539 return r
3640end
@@ -50,14 +54,25 @@ function store_methods:store(host, directives)
5054 end
5155 if max_age == 0 then
5256 -- delete from store
53- self .domains [host ] = nil
57+ local item = self .domains [host ]
58+ if item then
59+ self .expiry_heap :remove (item )
60+ self .domains [host ] = nil
61+ end
5462 else
5563 -- add to store
56- self .domains [host ] = setmetatable ({
64+ local old_item = self .domains [host ]
65+ if old_item then
66+ self .expiry_heap :remove (old_item )
67+ end
68+ local expires = now + max_age
69+ local item = setmetatable ({
5770 host = host ;
5871 includeSubdomains = directives .includeSubdomains ;
59- expires = now + max_age ;
72+ expires = expires ;
6073 }, store_item_mt )
74+ self .domains [host ] = item
75+ self .expiry_heap :insert (expires , item )
6176 end
6277 return true
6378end
@@ -83,12 +98,19 @@ function store_methods:check(host)
8398 return false
8499end
85100
101+ function store_methods :clean_due ()
102+ local next_expiring = self .expiry_heap :peek ()
103+ if not next_expiring then
104+ return (1e999 )
105+ end
106+ return next_expiring .expires
107+ end
108+
86109function store_methods :clean ()
87110 local now = self .time ()
88- for host , item in pairs (self .domains ) do
89- if item .expires < now then
90- self .domains [host ] = nil
91- end
111+ while self :clean_due () < now do
112+ local item = self .expiry_heap :pop ()
113+ self .domains [item .host ] = nil
92114 end
93115 return true
94116end
0 commit comments