webagent.lua 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. local skynet = require "skynet"
  2. local socket = require "skynet.socket"
  3. local cjson = require "cjson"
  4. local logger = require "logger"
  5. local httpd = require "http.httpd"
  6. local sockethelper = require "http.sockethelper"
  7. local urllib = require "http.url"
  8. local logger = require "logger"
  9. require "model.asset"
  10. require "model.loader"
  11. local traceback = debug.traceback
  12. local index = ...
  13. local skynet_retpack = skynet.retpack
  14. local socket_accept = socket.start
  15. local socket_close = socket.close
  16. local urllib_parse = urllib.parse
  17. local urllib_parse_query = urllib.parse_query
  18. local cjson_encode = cjson.encode
  19. local headers = {
  20. ['Access-Control-Allow-Origin'] = '*', -- 这里写允许访问的域名就可以了,允许所有人访问的话就写*
  21. ['Access-Control-Allow-Credentials'] = true,
  22. }
  23. local function response(fd, ...)
  24. local args = {...}
  25. local ok, err = httpd.write_response(sockethelper.writefunc(fd), args[1], args[2], headers)
  26. if not ok then
  27. -- if err == sockethelper.socket_error , that means socket closed.
  28. logger.error("fd = %d, %s", fd, err)
  29. end
  30. end
  31. local webpage = {}
  32. local function loadfile(url)
  33. local f = webpage[url]
  34. if f then return f end
  35. if url == "/favicon.ico" then
  36. -- discard the <favico.ico> request
  37. return nil
  38. end
  39. local ok, ret = pcall(require, "webpage" .. url)
  40. --local ok, ret = xpcall(require, traceback, "webpage" .. url)
  41. if not ok then
  42. logger.trace("webpage: ret"..ret)
  43. return nil
  44. end
  45. webpage[url] = ret
  46. return ret
  47. end
  48. local function dispatch_request(fd, method, url, body, ipaddr, recv_header)
  49. local path, query = urllib_parse(url)
  50. local f = loadfile(path)
  51. if not f then
  52. response(fd, 404, "Not Found")
  53. return
  54. end
  55. local ok, args = pcall(urllib_parse_query, query)
  56. if method == "POST" then
  57. query = body
  58. args = cjson.decode(body)
  59. end
  60. local resp, header = f(args, ipaddr, recv_header)
  61. if resp then
  62. if type(resp) == "table" then
  63. response(fd, 200, cjson_encode(resp), header)
  64. else
  65. assert(type(resp) == "string")
  66. response(fd, 200, resp, header)
  67. end
  68. end
  69. end
  70. local CMD = {}
  71. function CMD.dispatch(fd, ipaddr)
  72. socket_accept(fd)
  73. local code, url, method, header, body = httpd.read_request(sockethelper.readfunc(fd), 8192)
  74. if code then
  75. if code == 200 then
  76. dispatch_request(fd, method, url, body, ipaddr, header)
  77. else
  78. response(fd, code)
  79. end
  80. else
  81. if url == sockethelper.socket_error then
  82. logger.warn("socket closed")
  83. else
  84. logger.error(url)
  85. end
  86. end
  87. socket_close(fd)
  88. end
  89. skynet.start(function()
  90. logger.label(string.format("<Webagent %d>", index))
  91. skynet.dispatch("lua", function(session,_, cmd, ...)
  92. local f = assert(CMD[cmd])
  93. if session == 0 then
  94. f(...)
  95. else
  96. skynet_retpack(f(...))
  97. end
  98. end)
  99. end)