cookie.lua 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. local socket = require"socket"
  2. local http = require"socket.http"
  3. local url = require"socket.url"
  4. local ltn12 = require"ltn12"
  5. local token_class = '[^%c%s%(%)%<%>%@%,%;%:%\\%"%/%[%]%?%=%{%}]'
  6. local function unquote(t, quoted)
  7. local n = string.match(t, "%$(%d+)$")
  8. if n then n = tonumber(n) end
  9. if quoted[n] then return quoted[n]
  10. else return t end
  11. end
  12. local function parse_set_cookie(c, quoted, cookie_table)
  13. c = c .. ";$last=last;"
  14. local _, __, n, v, i = string.find(c, "(" .. token_class ..
  15. "+)%s*=%s*(.-)%s*;%s*()")
  16. local cookie = {
  17. name = n,
  18. value = unquote(v, quoted),
  19. attributes = {}
  20. }
  21. while 1 do
  22. _, __, n, v, i = string.find(c, "(" .. token_class ..
  23. "+)%s*=?%s*(.-)%s*;%s*()", i)
  24. if not n or n == "$last" then break end
  25. cookie.attributes[#cookie.attributes+1] = {
  26. name = n,
  27. value = unquote(v, quoted)
  28. }
  29. end
  30. cookie_table[#cookie_table+1] = cookie
  31. end
  32. local function split_set_cookie(s, cookie_table)
  33. cookie_table = cookie_table or {}
  34. -- remove quoted strings from cookie list
  35. local quoted = {}
  36. s = string.gsub(s, '"(.-)"', function(q)
  37. quoted[#quoted+1] = q
  38. return "$" .. #quoted
  39. end)
  40. -- add sentinel
  41. s = s .. ",$last="
  42. -- split into individual cookies
  43. i = 1
  44. while 1 do
  45. local _, __, cookie, next_token
  46. _, __, cookie, i, next_token = string.find(s, "(.-)%s*%,%s*()(" ..
  47. token_class .. "+)%s*=", i)
  48. if not next_token then break end
  49. parse_set_cookie(cookie, quoted, cookie_table)
  50. if next_token == "$last" then break end
  51. end
  52. return cookie_table
  53. end
  54. local function quote(s)
  55. if string.find(s, "[ %,%;]") then return '"' .. s .. '"'
  56. else return s end
  57. end
  58. local _empty = {}
  59. local function build_cookies(cookies)
  60. s = ""
  61. for i,v in ipairs(cookies or _empty) do
  62. if v.name then
  63. s = s .. v.name
  64. if v.value and v.value ~= "" then
  65. s = s .. '=' .. quote(v.value)
  66. end
  67. end
  68. if v.name and #(v.attributes or _empty) > 0 then s = s .. "; " end
  69. for j,u in ipairs(v.attributes or _empty) do
  70. if u.name then
  71. s = s .. u.name
  72. if u.value and u.value ~= "" then
  73. s = s .. '=' .. quote(u.value)
  74. end
  75. end
  76. if j < #v.attributes then s = s .. "; " end
  77. end
  78. if i < #cookies then s = s .. ", " end
  79. end
  80. return s
  81. end