|
- local minitel = require "minitel"
- local serial = require "serialization"
-
- local cfg = {["path"]="/boot/srv/frequest",["port"]=70}
-
- local function loadConfig(cfgpath)
- local f=io.open(cfgpath or "/boot/cfg/fserv.cfg","rb")
- if f then
- local ncfg = serial.unserialize(f:read("*a"))
- f:close()
- for k,v in pairs(ncfg) do
- cfg[k] = v
- end
- end
- end
-
- local function fileHandler(socket,rtype,path)
- syslog(string.format("[%s:%d] %s %s",socket.addr,socket.port,rtype,path),syslog.info,"fserv")
- if rtype == "t" then
- if fs.exists(path) and fs.isDirectory(path) then
- socket:write("d")
- for _,file in ipairs(fs.list(path)) do
- socket:write(file.."\n")
- end
- elseif fs.exists(path) and not fs.isDirectory(path) then
- local f,err = io.open(path,"rb")
- if f then
- socket:write("y")
- while true do
- local c = f:read(4096)
- if not c or c == "" then break end
- socket:write(c)
- end
- else
- socket:write("fFailed to open file: "..err)
- end
- else
- socket:write("nFile not found")
- end
- elseif rtype == "s" then
- if fs.exists(path) then
- local ftype = "f"
- if fs.isDirectory(path) then
- ftype = "d"
- end
- socket:write(string.format("y%s\n%d",ftype,fs.size(path)))
- else
- socket:write("nFile not found.")
- end
- else
- socket:write("fUnknown request type")
- end
- end
- local function httpHandler(socket,rtype,path)
- local tPath = fs.segments(path)
- local proto = table.remove(tPath,1)
- local url = string.format("%s://%s",proto,table.concat(tPath,"/"))
- local request = component.invoke(component.list("internet")(),"request",url)
- repeat
- coroutine.yield()
- until request.finishConnect()
- local code, message, headers = request.response()
- if code < 200 or code > 299 then
- socket:write(string.format("f%d\n%s",code,message))
- else
- socket:write("y")
- local data = ""
- repeat
- coroutine.yield()
- data = request.read()
- if data then
- socket:write(data)
- end
- until not data
- end
- end
-
- local function socketHandler(socket)
- return function()
- local line = nil
- repeat
- coroutine.yield()
- line = socket:read()
- until line
- local rtype, path = line:match("(.)(.+)")
- if fs.segments(path)[1] == "http" or fs.segments(path)[1] == "https" then
- httpHandler(socket,rtype,path)
- else
- path = (cfg.path .. "/" .. path:gsub("../","")):gsub("/+","/")
- fileHandler(socket,rtype,path)
- end
- socket:close()
- end
- end
-
- local function fileServer()
- while true do
- os.spawn(socketHandler(minitel.listen(70)),"fserv worker process")
- end
- end
-
- function start(cfgpath)
- loadConfig(cfgpath)
- return os.spawn(fileServer,"fserv")
- end
-
- return {start=start}
|