sjson-streaming.lua 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. -- Test sjson and GitHub API
  2. local s = tls.createConnection()
  3. s:on("connection", function(sck, c)
  4. sck:send("GET /repos/nodemcu/nodemcu-firmware/git/trees/master HTTP/1.0\r\nUser-agent: nodemcu/0.1\r\nHost: api.github.com\r\nConnection: close\r\nAccept: application/json\r\n\r\n")
  5. end)
  6. function startswith(String, Start)
  7. return string.sub(String, 1, string.len(Start)) == Start
  8. end
  9. local seenBlank = false
  10. local partial
  11. local wantval = { tree = 1, path = 1, url = 1 }
  12. -- Make an sjson decoder that only keeps certain fields
  13. local decoder = sjson.decoder({
  14. metatable =
  15. {
  16. __newindex = function(t, k, v)
  17. if wantval[k] or type(k) == "number" then
  18. rawset(t, k, v)
  19. end
  20. end
  21. }
  22. })
  23. local function handledata(s)
  24. decoder:write(s)
  25. end
  26. -- The receive callback is somewhat gnarly as it has to deal with find the end of the header
  27. -- and having the newline sequence split across packets
  28. s:on("receive", function(sck, c)
  29. if partial then
  30. c = partial .. c
  31. partial = nil
  32. end
  33. if seenBlank then
  34. handledata(c)
  35. return
  36. end
  37. while c do
  38. if startswith(c, "\r\n") then
  39. seenBlank = true
  40. c = c:sub(3)
  41. handledata(c)
  42. return
  43. end
  44. local s, e = c:find("\r\n")
  45. if s then
  46. -- Throw away line
  47. c = c:sub(e + 1)
  48. else
  49. partial = c
  50. c = nil
  51. end
  52. end
  53. end)
  54. local function getresult()
  55. local result = decoder:result()
  56. -- This gets the resulting decoded object with only the required fields
  57. print(result['tree'][4]['path'], "is at",
  58. result['tree'][4]['url'])
  59. end
  60. s:on("disconnection", getresult)
  61. s:on("reconnection", getresult)
  62. -- Make it all happen!
  63. s:connect(443, "api.github.com")