* Preliminary module implementation for Luci HTTPD
This commit is contained in:
parent
37ab75aea5
commit
71beb64a22
2 changed files with 176 additions and 0 deletions
22
libs/httpd/luasrc/httpd/handler/file.lua
Normal file
22
libs/httpd/luasrc/httpd/handler/file.lua
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module("luci.httpd.handler.file", package.seeall)
|
||||||
|
require("luci.httpd.module")
|
||||||
|
require("luci.fs")
|
||||||
|
require("ltn12")
|
||||||
|
|
||||||
|
Simple = luci.util.class(luci.httpd.module.Handler)
|
||||||
|
Response = luci.httpd.module.Response
|
||||||
|
|
||||||
|
function Simple.__init__(self, docroot)
|
||||||
|
luci.httpd.module.Handler.__init__(self)
|
||||||
|
self.docroot = docroot
|
||||||
|
end
|
||||||
|
|
||||||
|
function Simple.handle(self, request, sourcein, sinkerr)
|
||||||
|
local file = self.docroot .. request.env.REQUEST_URI:gsub("../", "")
|
||||||
|
local size = luci.fs.stat(file, "size")
|
||||||
|
if size then
|
||||||
|
return Response(200, {["Content-Length"] = size}), ltn12.source.file(io.open(file))
|
||||||
|
else
|
||||||
|
return Response(404)
|
||||||
|
end
|
||||||
|
end
|
154
libs/httpd/luasrc/httpd/module.lua
Normal file
154
libs/httpd/luasrc/httpd/module.lua
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
--[[
|
||||||
|
LuCI - Lua Configuration Interface
|
||||||
|
|
||||||
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
]]--
|
||||||
|
module("luci.httpd.module", package.seeall)
|
||||||
|
require("luci.util")
|
||||||
|
require("ltn12")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Server handler implementation
|
||||||
|
Handler = luci.util.class()
|
||||||
|
|
||||||
|
-- Constructor
|
||||||
|
function Handler.__init__(self)
|
||||||
|
self.filters = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Adds a filter to the filter chain
|
||||||
|
function Handler.addfilter(self, filter)
|
||||||
|
table.insert(self.filters, filter)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Creates a failure reply
|
||||||
|
function Handler.failure(self, message)
|
||||||
|
response = {
|
||||||
|
status = 500,
|
||||||
|
headers = {
|
||||||
|
["Content-Type"] = "text/plain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceout = ltn12.source.string(message)
|
||||||
|
|
||||||
|
return response, sourceout
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Processes a request
|
||||||
|
function Handler.process(self, request, sourcein, sinkout, sinkerr)
|
||||||
|
-- Process incoming filters
|
||||||
|
for i, f in ipairs(self.filters) do
|
||||||
|
local i = f:get("input")
|
||||||
|
|
||||||
|
if i then
|
||||||
|
sourcein = ltn12.source.chain(sourcein, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
if f.request then
|
||||||
|
f:request(request)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run the handler
|
||||||
|
local stat, response, sourceout = luci.util.copcall(
|
||||||
|
self.handle, self, request, sourcein, sinkerr
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Check for any errors
|
||||||
|
if not stat then
|
||||||
|
response, sourceout = self:failure(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check data
|
||||||
|
if not luci.util.instanceof(response, Response) then
|
||||||
|
response, sourceout = self:failure("Core error: Invalid module response!")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Process outgoing filters
|
||||||
|
for i, f in ipairs(self.filters) do
|
||||||
|
local o = f:get("output")
|
||||||
|
|
||||||
|
if o then
|
||||||
|
sourceout = ltn12.source.chain(sourceout, o)
|
||||||
|
end
|
||||||
|
|
||||||
|
if f.response then
|
||||||
|
f:response(response)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Print status and headers
|
||||||
|
sinkout("HTTP/1.1 " .. response.status .. " " .. statusmsg[response.status] .. "\n")
|
||||||
|
for k, v in pairs(response.headers) do
|
||||||
|
sinkout(k .. ": " .. v .. "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- End of Headers
|
||||||
|
sinkout("\n")
|
||||||
|
|
||||||
|
-- Pump content
|
||||||
|
if sourceout then
|
||||||
|
ltn12.pump.all(sourceout, sinkout)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Server Filter implementation
|
||||||
|
Filter = luci.util.class()
|
||||||
|
|
||||||
|
function Filter.get(self, name)
|
||||||
|
return self[name] and function(...) return self[name](self, ...) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Filters the incoming body stream
|
||||||
|
-- abstract function Filter.input(chunk)
|
||||||
|
|
||||||
|
-- Filters the outgoing body stream
|
||||||
|
-- abstract function Filter.output(chunk)
|
||||||
|
|
||||||
|
-- Filters the request object
|
||||||
|
-- abstract function Filter.request(request)
|
||||||
|
|
||||||
|
-- Filters the response object
|
||||||
|
-- abstract function Filter.response(response)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Handler Response
|
||||||
|
Response = luci.util.class()
|
||||||
|
|
||||||
|
function Response.__init__(self, status, headers)
|
||||||
|
self.status = tonumber(status) or 200
|
||||||
|
self.headers = (type(headers) == "table") and headers or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function Response.addheader(self, key, value)
|
||||||
|
self.headers[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
function Response.setstatus(self, status)
|
||||||
|
self.status = status
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Status codes
|
||||||
|
statusmsg = {
|
||||||
|
[200] = "OK",
|
||||||
|
[404] = "Not Found",
|
||||||
|
[500] = "Internal Server Error",
|
||||||
|
}
|
Loading…
Reference in a new issue