Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.3KB

  1. local minitel = require "minitel"
  2. local serial = require "serialization"
  3. local cfg = {["path"]="/boot/srv/frequest",["port"]=70}
  4. f=io.open("/boot/cfg/fserv.cfg","rb")
  5. if f then
  6. local ncfg = serial.unserialize(f:read("*a"))
  7. f:close()
  8. for k,v in pairs(ncfg) do
  9. cfg[k] = v
  10. end
  11. end
  12. local function fileHandler(socket,rtype,path)
  13. syslog(string.format("[%s:%d] %s %s",socket.addr,socket.port,rtype,path),syslog.info,"fserv")
  14. if rtype == "t" then
  15. if fs.exists(path) and fs.isDirectory(path) then
  16. socket:write("d")
  17. for _,file in ipairs(fs.list(path)) do
  18. socket:write(file.."\n")
  19. end
  20. elseif fs.exists(path) and not fs.isDirectory(path) then
  21. local f,err = io.open(path,"rb")
  22. if f then
  23. socket:write("y")
  24. while true do
  25. local c = f:read(4096)
  26. if not c or c == "" then break end
  27. socket:write(c)
  28. end
  29. else
  30. socket:write("fFailed to open file: "..err)
  31. end
  32. else
  33. socket:write("nFile not found")
  34. end
  35. elseif rtype == "s" then
  36. if fs.exists(path) then
  37. local ftype = "f"
  38. if fs.isDirectory(path) then
  39. ftype = "d"
  40. end
  41. socket:write(string.format("y%s\n%d",ftype,fs.size(path)))
  42. else
  43. socket:write("nFile not found.")
  44. end
  45. else
  46. socket:write("fUnknown request type")
  47. end
  48. end
  49. local function httpHandler(socket,rtype,path)
  50. local tPath = fs.segments(path)
  51. local proto = table.remove(tPath,1)
  52. local url = string.format("%s://%s",proto,table.concat(tPath,"/"))
  53. local request = component.invoke(component.list("internet")(),"request",url)
  54. repeat
  55. coroutine.yield()
  56. until request.finishConnect()
  57. local code, message, headers = request.response()
  58. if code < 200 or code > 299 then
  59. socket:write(string.format("f%d\n%s",code,message))
  60. else
  61. local data = ""
  62. repeat
  63. coroutine.yield()
  64. data = request.read()
  65. if data then
  66. socket:write(data)
  67. end
  68. until not data
  69. end
  70. end
  71. local function socketHandler(socket)
  72. return function()
  73. local line = nil
  74. repeat
  75. coroutine.yield()
  76. line = socket:read()
  77. until line
  78. local rtype, path = line:match("(.)(.+)")
  79. if fs.segments(path)[1] == "http" or fs.segments(path)[1] == "https" then
  80. httpHandler(socket,rtype,path)
  81. else
  82. path = (cfg.path .. "/" .. path:gsub("../","")):gsub("/+","/")
  83. fileHandler(socket,rtype,path)
  84. end
  85. socket:close()
  86. end
  87. end
  88. while true do
  89. os.spawn(socketHandler(minitel.listen(70)),"fserv worker process")
  90. end