cookies.nim 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements helper procs for parsing Cookies.
  10. import strtabs, times
  11. proc parseCookies*(s: string): StringTableRef =
  12. ## parses cookies into a string table.
  13. ##
  14. ## The proc is meant to parse the Cookie header set by a client, not the
  15. ## "Set-Cookie" header set by servers.
  16. ##
  17. ## Example:
  18. ##
  19. ## .. code-block::Nim
  20. ## doAssert parseCookies("a=1; foo=bar") == {"a": 1, "foo": "bar"}.newStringTable
  21. result = newStringTable(modeCaseInsensitive)
  22. var i = 0
  23. while true:
  24. while i < s.len and (s[i] == ' ' or s[i] == '\t'): inc(i)
  25. var keystart = i
  26. while i < s.len and s[i] != '=': inc(i)
  27. var keyend = i-1
  28. if i >= s.len: break
  29. inc(i) # skip '='
  30. var valstart = i
  31. while i < s.len and s[i] != ';': inc(i)
  32. result[substr(s, keystart, keyend)] = substr(s, valstart, i-1)
  33. if i >= s.len: break
  34. inc(i) # skip ';'
  35. proc setCookie*(key, value: string, domain = "", path = "",
  36. expires = "", noName = false,
  37. secure = false, httpOnly = false): string =
  38. ## Creates a command in the format of
  39. ## ``Set-Cookie: key=value; Domain=...; ...``
  40. result = ""
  41. if not noName: result.add("Set-Cookie: ")
  42. result.add key & "=" & value
  43. if domain != "": result.add("; Domain=" & domain)
  44. if path != "": result.add("; Path=" & path)
  45. if expires != "": result.add("; Expires=" & expires)
  46. if secure: result.add("; Secure")
  47. if httpOnly: result.add("; HttpOnly")
  48. proc setCookie*(key, value: string, expires: DateTime|Time,
  49. domain = "", path = "", noName = false,
  50. secure = false, httpOnly = false): string =
  51. ## Creates a command in the format of
  52. ## ``Set-Cookie: key=value; Domain=...; ...``
  53. return setCookie(key, value, domain, path,
  54. format(expires.utc, "ddd',' dd MMM yyyy HH:mm:ss 'GMT'"),
  55. noname, secure, httpOnly)
  56. when isMainModule:
  57. let expire = fromUnix(0) + 1.seconds
  58. let cookies = [
  59. setCookie("test", "value", expire),
  60. setCookie("test", "value", expire.local),
  61. setCookie("test", "value", expire.utc)
  62. ]
  63. let expected = "Set-Cookie: test=value; Expires=Thu, 01 Jan 1970 00:00:01 GMT"
  64. doAssert cookies == [expected, expected, expected]
  65. let table = parseCookies("uid=1; kp=2")
  66. doAssert table["uid"] == "1"
  67. doAssert table["kp"] == "2"