cookie.lua 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. -- The MIT License (MIT)
  2. --
  3. -- Copyright (c) 2014 Cyril David <cyx@cyx.is>
  4. --
  5. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  6. -- of this software and associated documentation files (the "Software"), to deal
  7. -- in the Software without restriction, including without limitation the rights
  8. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. -- copies of the Software, and to permit persons to whom the Software is
  10. -- furnished to do so, subject to the following conditions:
  11. --
  12. -- The above copyright notice and this permission notice shall be included in
  13. -- all copies or substantial portions of the Software.
  14. --
  15. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. -- THE SOFTWARE.
  22. local uri = require("lib/uri-f570bf7")
  23. local insert = table.insert
  24. local concat = table.concat
  25. local format = string.format
  26. local gmatch = string.gmatch
  27. local sub = string.sub
  28. local gsub = string.gsub
  29. local find = string.find
  30. -- identity function
  31. local function identity(val)
  32. return val
  33. end
  34. -- trim and remove double quotes
  35. local function clean(str)
  36. local s = gsub(str, "^%s*(.-)%s*$", "%1")
  37. if sub(s, 1, 1) == '"' then
  38. s = sub(s, 2, -2)
  39. end
  40. return s
  41. end
  42. -- given a unix timestamp, return a utc string
  43. local function to_utc_string(time)
  44. return os.date("%a, %d %b %Y %H:%I:%S GMT", time)
  45. end
  46. local CODEX = {
  47. {"max_age", "Max-Age=%d", identity},
  48. {"domain", "Domain=%s", identity},
  49. {"path", "Path=%s", identity},
  50. {"expires", "Expires=%s", to_utc_string},
  51. {"http_only", "HttpOnly", identity},
  52. {"secure", "Secure", identity},
  53. }
  54. local function build(dict, options)
  55. options = options or {}
  56. local res = {}
  57. for k, v in pairs(dict) do
  58. insert(res, format("%s=%s", k, uri.encode(v)))
  59. end
  60. for _, tuple in ipairs(CODEX) do
  61. local key, template, fn = unpack(tuple)
  62. local val = options[key]
  63. if val then
  64. insert(res, format(template, fn(val)))
  65. end
  66. end
  67. return concat(res, "; ")
  68. end
  69. local function parse(data)
  70. local res = {}
  71. for pair in gmatch(data, "[^;]+") do
  72. local eq = find(pair, "=")
  73. if eq then
  74. local key = clean(sub(pair, 1, eq-1))
  75. local val = clean(sub(pair, eq+1))
  76. if not res[key] then
  77. res[key] = uri.decode(val)
  78. end
  79. end
  80. end
  81. return res
  82. end
  83. return {
  84. build = build,
  85. parse = parse
  86. }