Skip to content

Commit f611bf0

Browse files
committed
http/cookie: Add bake function based on @RyanSquared's code
See #79
1 parent 271a51a commit f611bf0

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

http/cookie.lua

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,55 @@ local sane_cookie_date = http_patts.IMF_fixdate * EOF
1313
local Cookie = http_patts.Cookie * EOF
1414
local Set_Cookie = http_patts.Set_Cookie * EOF
1515

16+
local function bake(name, value, expiry_time, domain, path, secure_only, http_only, same_site)
17+
-- This function is optimised to only do one concat operation at the end
18+
local cookie = { name, "=", value }
19+
local n = 3
20+
if expiry_time and expiry_time ~= (1e999) then
21+
-- Prefer Expires over Max-age unless it is a deletion request
22+
if expiry_time == (-1e999) then
23+
n = n + 1
24+
cookie[n] = "; Max-Age=0"
25+
else
26+
n = n + 2
27+
cookie[n-1] = "; Expires="
28+
cookie[n] = http_util.imf_date(expiry_time)
29+
end
30+
end
31+
if domain then
32+
n = n + 2
33+
cookie[n-1] = "; Domain="
34+
cookie[n] = domain
35+
end
36+
if path then
37+
n = n + 2
38+
cookie[n-1] = "; Path="
39+
cookie[n] = http_util.encodeURI(path)
40+
end
41+
if secure_only then
42+
n = n + 1
43+
cookie[n] = "; Secure"
44+
end
45+
if http_only then
46+
n = n + 1
47+
cookie[n] = "; HttpOnly"
48+
end
49+
-- https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-02#section-5.2
50+
if same_site then
51+
local v
52+
if same_site == "strict" then
53+
v = "; SameSite=Strict"
54+
elseif same_site == "lax" then
55+
v = "; SameSite=Lax"
56+
else
57+
error('invalid value for same_site, expected "strict" or "lax"')
58+
end
59+
n = n + 1
60+
cookie[n] = v
61+
end
62+
return table.concat(cookie, "", 1, n)
63+
end
64+
1665
local function parse_cookie(cookie_header)
1766
return Cookie:match(cookie_header)
1867
end
@@ -91,6 +140,7 @@ function cookie_methods:netscape_format()
91140
self.value)
92141
end
93142

143+
94144
local default_psl
95145
if has_psl and psl.latest then
96146
default_psl = psl.latest()
@@ -639,6 +689,8 @@ function store_methods:save_to_file(file)
639689
end
640690

641691
return {
692+
bake = bake;
693+
642694
parse_cookie = parse_cookie;
643695
parse_setcookie = parse_setcookie;
644696

spec/cookie_spec.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ describe("cookie module", function()
198198
assert.same("", s:lookup("example.com", "/", true, true, false, "other.com", false))
199199
end)
200200
end)
201+
it("can bake cookies", function()
202+
assert.same("foo=bar", http_cookie.bake("foo", "bar"))
203+
assert.same("foo=bar; Max-Age=0", http_cookie.bake("foo", "bar", -math.huge))
204+
assert.same("foo=bar; Expires=Thu, 01 Jan 1970 00:00:00 GMT", http_cookie.bake("foo", "bar", 0))
205+
assert.same("foo=bar; Max-Age=0; Domain=example.com; Path=/path; Secure; HttpOnly; SameSite=Strict",
206+
http_cookie.bake("foo", "bar", -math.huge, "example.com", "/path", true, true, "strict"))
207+
assert.same("foo=bar; Max-Age=0; Domain=example.com; Path=/path; Secure; HttpOnly; SameSite=Lax",
208+
http_cookie.bake("foo", "bar", -math.huge, "example.com", "/path", true, true, "lax"))
209+
assert.has.errors(function()
210+
http_cookie.bake("foo", "bar", -math.huge, "example.com", "/path", true, true, "somethingelse")
211+
end, [[invalid value for same_site, expected "strict" or "lax"]])
212+
end)
201213
it("can dump a netscape format cookiejar", function()
202214
local s = http_cookie.new_store()
203215
assert(s:store("example.com", "/", true, true, "example.com", http_cookie.parse_setcookie("foo=FOO;")))

0 commit comments

Comments
 (0)