* Added support for CGI SGI

This commit is contained in:
Steven Barth 2008-06-15 17:45:10 +00:00
parent 3455ee6d8d
commit eae0e44798
8 changed files with 106 additions and 68 deletions

View file

@ -80,7 +80,7 @@ function index()
page.setuser = "nobody" page.setuser = "nobody"
page.setgroup = "nogroup" page.setgroup = "nogroup"
local vars = luci.http.getvalue() local vars = luci.http.formvalue()
local span = vars.timespan or nil local span = vars.timespan or nil
for i, plugin in luci.util.vspairs( tree:plugins() ) do for i, plugin in luci.util.vspairs( tree:plugins() ) do
@ -148,7 +148,7 @@ function statistics_render()
require("luci.template") require("luci.template")
require("luci.model.uci") require("luci.model.uci")
local vars = luci.http.getvalue() local vars = luci.http.formvalue()
local req = luci.dispatcher.context.request local req = luci.dispatcher.context.request
local path = luci.dispatcher.context.dispatched.path local path = luci.dispatcher.context.dispatched.path
local uci = luci.model.uci local uci = luci.model.uci

View file

@ -75,6 +75,9 @@ function flash(image, kpattern)
return os.execute(cmd) return os.execute(cmd)
end end
-- Returns the enivornment
getenv = posix.getenv
-- Returns the hostname -- Returns the hostname
function hostname() function hostname()
return io.lines("/proc/sys/kernel/hostname")() return io.lines("/proc/sys/kernel/hostname")()

2
libs/sgi-cgi/Makefile Normal file
View file

@ -0,0 +1,2 @@
include ../../build/config.mk
include ../../build/module.mk

View file

@ -0,0 +1,4 @@
#!/usr/bin/lua
require("luci.sgi.cgi")
luci.dispatcher.indexcache = "/tmp/.luciindex"
luci.sgi.cgi.run()

View file

@ -0,0 +1,57 @@
--[[
LuCI - SGI-Module for CGI
Description:
Server Gateway Interface for CGI
FileId:
$Id$
License:
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.sgi.cgi", package.seeall)
require("luci.http")
require("luci.sys")
require("luci.dispatcher")
function run()
local r = luci.http.Request(luci.sys.getenv(), io.stdin, io.stderr)
local x = coroutine.create(luci.dispatcher.httpdispatch)
while coroutine.status(x) ~= "dead" do
local res, id, data1, data2 = coroutine.resume(x, r)
if not res then
print("Status: 500 Internal Server Error")
print("Content-Type: text/plain\n")
print(id)
break;
end
if id == 1 then
io.write("Status: " .. tostring(data1) .. " " .. data2 .. "\n")
elseif id == 2 then
io.write(data1 .. ": " .. data2 .. "\n")
elseif id == 3 then
io.write("\n")
elseif id == 4 then
io.write(data1)
end
end
end

View file

@ -84,7 +84,7 @@ end
function httpdispatch(request) function httpdispatch(request)
luci.http.context.request = request luci.http.context.request = request
context.request = {} context.request = {}
local pathinfo = request.env.PATH_INFO or "" local pathinfo = request:getenv("PATH_INFO") or ""
for node in pathinfo:gmatch("[^/]+") do for node in pathinfo:gmatch("[^/]+") do
table.insert(context.request, node) table.insert(context.request, node)

View file

@ -38,47 +38,51 @@ Request = luci.util.class()
function Request.__init__(self, env, instream, errstream) function Request.__init__(self, env, instream, errstream)
self.input = instream self.input = instream
self.error = errstream self.error = errstream
-- Formdata tables
self.get = {}
self.post = {}
-- Provide readline function
self.inputreader = self.input.readline
or self.input.read and function() return self.input:read() end
or self.input.receive and function() return self.input:receive() end
or function() return nil end
-- File handler -- File handler
self.filehandler = function() end self.filehandler = function() end
-- Environment table -- HTTP-Message table
self.env = env self.message = {
env = env,
headers = {},
params = luci.http.protocol.urldecode_params("?"..env.QUERY_STRING),
}
setmetatable(self.get, {__index = setmetatable(self.message.params, {__index =
function(tbl, key) function(tbl, key)
tbl = luci.http.protocol.urldecode_params(self.env.QUERY_STRING) luci.http.protocol.parse_message_body(
self.inputreader,
self.message,
self.filehandler
)
setmetatable(tbl, nil) setmetatable(tbl, nil)
return rawget(tbl, key) return rawget(tbl, key)
end }) end
})
setmetatable(self.post, {__index =
function(tbl, key)
tbl = luci.http.protocol.
setmetatable(tbl, nil)
return rawget(tbl, key)
end })
end end
function Request.formvalue(self, name, default) function Request.formvalue(self, name, default)
return tostring(self.post[name] or self.get[name] or default) if name then
return self.message.params[name] and tostring(self.message.params[name]) or default
else
return self.message.params
end
end end
function Request.formvaluetable(self, prefix) function Request.formvaluetable(self, prefix)
local vals = {} local vals = {}
prefix = prefix and prefix .. "." or "." prefix = prefix and prefix .. "." or "."
for k, v in pairs(self.getvalue()) do local void = self.message.params[nil]
if k:find(prefix, 1, true) == 1 then for k, v in pairs(self.message.params) do
vals[k:sub(#prefix + 1)] = tostring(v)
end
end
for k, v in pairs(self.postvalue()) do
if k:find(prefix, 1, true) == 1 then if k:find(prefix, 1, true) == 1 then
vals[k:sub(#prefix + 1)] = tostring(v) vals[k:sub(#prefix + 1)] = tostring(v)
end end
@ -88,17 +92,7 @@ function Request.formvaluetable(self, prefix)
end end
function Request.getenv(self, name) function Request.getenv(self, name)
return name and self.env[name] or self.env return name and self.message.env[name] or self.message.env
end
function Request.getvalue(self, name)
local void = self.get[nil]
return name and self.get[name] or self.get
end
function Request.postvalue(self, name)
local void = self.post[nil]
return name and self.post[name] or self.post
end end
function Request.setfilehandler(self, callback) function Request.setfilehandler(self, callback)
@ -212,20 +206,3 @@ end
urldecode = luci.http.protocol.urldecode urldecode = luci.http.protocol.urldecode
urlencode = luci.http.protocol.urlencode urlencode = luci.http.protocol.urlencode
--[[
function urldecode(str)
str = str:gsub("+", " ")
str = str:gsub("%%(%x%x)",
function(h) return string.char(tonumber(h,16)) end)
str = str:gsub("\r\n", "\n")
return str
end
function urlencode(str)
str = str:gsub("\n", "\r\n")
str = str:gsub("([^%w ])",
function (c) return string.format ("%%%02X", string.byte(c)) end)
str = str:gsub(" ", "+")
return str
end
]]--

View file

@ -370,9 +370,6 @@ function parse_message_header( data )
message.headers = hdrs message.headers = hdrs
-- Get content
local clen = ( hdrs['Content-Length'] or HTTP_MAX_CONTENT ) + 0
-- Process get parameters -- Process get parameters
if ( method == "get" or method == "post" ) and if ( method == "get" or method == "post" ) and
message.request_uri:match("?") message.request_uri:match("?")
@ -421,25 +418,24 @@ end
function parse_message_body( reader, message, filecb ) function parse_message_body( reader, message, filecb )
if type(message) == "table" then if type(message) == "table" then
local env = message.env
local hdrs = message.headers local clen = ( env.CONTENT_LENGTH or HTTP_MAX_CONTENT ) + 0
-- Process post method -- Process post method
if message.request_method == "post" and hdrs['Content-Type'] then if env.REQUEST_METHOD:lower() == "post" and env.CONTENT_TYPE then
-- Is it multipart/form-data ? -- Is it multipart/form-data ?
if hdrs['Content-Type']:match("^multipart/form%-data") then if env.CONTENT_TYPE:match("^multipart/form%-data") then
for k, v in pairs( mimedecode( for k, v in pairs( mimedecode(
reader, reader,
hdrs['Content-Type']:match("boundary=(.+)"), env.CONTENT_TYPE:match("boundary=(.+)"),
filecb filecb
) ) do ) ) do
message.params[k] = v message.params[k] = v
end end
-- Is it x-www-urlencoded? -- Is it x-www-form-urlencoded?
elseif hdrs['Content-Type'] == 'application/x-www-urlencoded' then elseif env.CONTENT_TYPE:match('^application/x%-www%-form%-urlencoded') then
-- XXX: readline isn't the best solution here -- XXX: readline isn't the best solution here
for chunk in reader do for chunk in reader do
for k, v in pairs( urldecode_params( chunk ) ) do for k, v in pairs( urldecode_params( chunk ) ) do
@ -458,7 +454,6 @@ function parse_message_body( reader, message, filecb )
-- If a file callback is given then feed it line by line, else -- If a file callback is given then feed it line by line, else
-- store whole buffer in message.content -- store whole buffer in message.content
else else
for chunk in reader do for chunk in reader do
-- We have a callback, feed it. -- We have a callback, feed it.