9
9
10
10
# # This module implements helper procs for parsing Cookies.
11
11
12
- import strtabs, times
12
+ import std/ [strtabs, times, options]
13
+
14
+
15
+ type
16
+ SameSite * {.pure .} = enum # # The SameSite cookie attribute.
17
+ # # `Default` means that `setCookie`
18
+ # # proc will not set `SameSite` attribute.
19
+ Default , None , Lax , Strict
13
20
14
21
proc parseCookies * (s: string ): StringTableRef =
15
- # # parses cookies into a string table.
22
+ # # Parses cookies into a string table.
16
23
# #
17
24
# # The proc is meant to parse the Cookie header set by a client, not the
18
25
# # "Set-Cookie" header set by servers.
19
- # #
20
- # # Example:
21
- # #
22
- # # .. code-block::Nim
23
- # # doAssert parseCookies("a=1; foo=bar") == {"a": 1, "foo": " bar"}.newStringTable
26
+ runnableExamples:
27
+ import std / strtabs
28
+ let cookieJar = parseCookies ( " a=1; foo=bar " )
29
+ assert cookieJar[ " a " ] == " 1 "
30
+ assert cookieJar[ " foo" ] == " bar"
24
31
25
32
result = newStringTable (modeCaseInsensitive)
26
33
var i = 0
@@ -39,9 +46,10 @@ proc parseCookies*(s: string): StringTableRef =
39
46
40
47
proc setCookie * (key, value: string , domain = " " , path = " " ,
41
48
expires = " " , noName = false ,
42
- secure = false , httpOnly = false ): string =
49
+ secure = false , httpOnly = false ,
50
+ maxAge = none (int ), sameSite = SameSite .Default ): string =
43
51
# # Creates a command in the format of
44
- # # `` Set-Cookie: key=value; Domain=...; ...` `
52
+ # # `Set-Cookie: key=value; Domain=...; ...`
45
53
result = " "
46
54
if not noName: result .add (" Set-Cookie: " )
47
55
result .add key & " =" & value
@@ -50,12 +58,19 @@ proc setCookie*(key, value: string, domain = "", path = "",
50
58
if expires != " " : result .add (" ; Expires=" & expires)
51
59
if secure: result .add (" ; Secure" )
52
60
if httpOnly: result .add (" ; HttpOnly" )
61
+ if maxAge.isSome: result .add (" ; Max-Age=" & $ maxAge.unsafeGet)
62
+
63
+ if sameSite != SameSite .Default :
64
+ if sameSite == SameSite .None :
65
+ doAssert secure, " Cookies with SameSite=None must specify the Secure attribute!"
66
+ result .add (" ; SameSite=" & $ sameSite)
53
67
54
68
proc setCookie * (key, value: string , expires: DateTime | Time ,
55
69
domain = " " , path = " " , noName = false ,
56
- secure = false , httpOnly = false ): string =
70
+ secure = false , httpOnly = false ,
71
+ maxAge = none (int ), sameSite = SameSite .Default ): string =
57
72
# # Creates a command in the format of
58
- # # `` Set-Cookie: key=value; Domain=...; ...` `
59
- return setCookie (key, value, domain, path,
73
+ # # `Set-Cookie: key=value; Domain=...; ...`
74
+ result = setCookie (key, value, domain, path,
60
75
format (expires.utc, " ddd',' dd MMM yyyy HH:mm:ss 'GMT'" ),
61
- noname, secure, httpOnly)
76
+ noname, secure, httpOnly, maxAge, sameSite )
0 commit comments