From 71beb64a228c1581306c22eef4b59c9594c586ae Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Tue, 17 Jun 2008 16:16:27 +0000 Subject: [PATCH] * Preliminary module implementation for Luci HTTPD --- libs/httpd/luasrc/httpd/handler/file.lua | 22 +++++ libs/httpd/luasrc/httpd/module.lua | 154 +++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 libs/httpd/luasrc/httpd/handler/file.lua create mode 100644 libs/httpd/luasrc/httpd/module.lua diff --git a/libs/httpd/luasrc/httpd/handler/file.lua b/libs/httpd/luasrc/httpd/handler/file.lua new file mode 100644 index 000000000..eb5aafd78 --- /dev/null +++ b/libs/httpd/luasrc/httpd/handler/file.lua @@ -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 \ No newline at end of file diff --git a/libs/httpd/luasrc/httpd/module.lua b/libs/httpd/luasrc/httpd/module.lua new file mode 100644 index 000000000..bb22798fe --- /dev/null +++ b/libs/httpd/luasrc/httpd/module.lua @@ -0,0 +1,154 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2008 Steven Barth + +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", +} \ No newline at end of file -- 2.11.0