* libs/http: Use env-Variables instead of headers for parse_message_body and subsequent functions
* libs/http: Added missing urldecode call for parsing urlencoded params
* libs/web: Ported luci.http to use ltn12 sources and sinks instead of sockets or file pointers
* libs/sgi-cgi, libs/sgi-webuci, libs/sgi-wsapi: Updated to work with new luci.http.Request ABI
rawset(self, thread, {})
end
rawget(self, thread)[key] = value
+
+ -- Avoid memory leaks by removing abandoned stores
+ for k, v in pairs(self) do
+ if type(k) == "thread" and coroutine.status(k) == "dead" then
+ rawset(self, k, nil)
+ end
+ end
end
setmetatable(tbl, {__index = get, __newindex = set})
if chunk ~= nil then
-- Check for Content-Length
- if msg.headers['Content-Length'] then
- msg.content_length = tonumber(msg.headers['Content-Length'])
+ if msg.env.CONTENT_LENGTH then
+ msg.content_length = tonumber(msg.env.CONTENT_LENGTH)
if msg.content_length <= HTTP_MAX_CONTENT then
-- Initialize buffer
-- Process urldecoding stream, read and validate parameter key
process_states['urldecode-key'] = function( msg, chunk, filecb )
-
if chunk ~= nil then
-- Prevent oversized requests
else
msg._urldeccallback = function( chunk, eof )
msg.params[key] = msg.params[key] .. chunk
+
+ -- FIXME: Use a filter
+ if eof then
+ msg.params[key] = urldecode( msg.params[key] )
+ end
end
end
function mimedecode_message_body( source, msg, filecb )
-- Find mime boundary
- if msg and msg.headers['Content-Type'] then
+ if msg and msg.env.CONTENT_TYPE then
- local bound = msg.headers['Content-Type']:match("^multipart/form%-data; boundary=(.+)")
+ local bound = msg.env.CONTENT_TYPE:match("^multipart/form%-data; boundary=(.+)")
if bound then
msg.mime_boundary = bound
REQUEST_METHOD = msg.request_method:upper();
REQUEST_URI = msg.request_uri;
SCRIPT_NAME = msg.request_uri:gsub("?.+$","");
- SCRIPT_FILENAME = "" -- XXX implement me
+ SCRIPT_FILENAME = ""; -- XXX implement me
+ SERVER_PROTOCOL = "HTTP/" .. msg.http_version
}
-- Populate HTTP_* environment variables
elseif msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
msg.env.CONTENT_TYPE == "application/x-www-form-urlencoded"
then
-
return urldecode_message_body( source, msg, filecb )
+
-- Unhandled encoding
-- If a file callback is given then feed it line by line, else
]]--
module("luci.sgi.cgi", package.seeall)
+require("ltn12")
require("luci.http")
require("luci.sys")
require("luci.dispatcher")
function run()
- local r = luci.http.Request(luci.sys.getenv(), io.stdin, io.stderr)
+ local r = luci.http.Request(
+ luci.sys.getenv(),
+ ltn12.source.file(io.stdin),
+ ltn12.sink.file(io.stderr)
+ )
local x = coroutine.create(luci.dispatcher.httpdispatch)
]]--
module("luci.sgi.webuci", package.seeall)
+require("ltn12")
require("luci.http")
require("luci.util")
require("luci.dispatcher")
function run(env, vars)
- local r = luci.http.Request(env, {}, io.stderr)
+ local r = luci.http.Request(
+ env,
+ ltn12.source.empty(),
+ ltn12.sink.file(io.stderr)
+ )
+
r.message.params = vars
local x = coroutine.create(luci.dispatcher.httpdispatch)
]]--
module("luci.sgi.wsapi", package.seeall)
+require("ltn12")
require("luci.http")
require("luci.dispatcher")
require("luci.http.protocol")
function run(wsapi_env)
- local r = luci.http.Request(wsapi_env, wsapi_env.input, wsapi_env.error)
- r.postds = function() return wsapi.request.parse_post_data(wsapi_env) end
- r.getds = function() return wsapi.request.parse_qs(wsapi_env.QUERY_STRING) end
+ local r = luci.http.Request(
+ wsapi_env,
+ ltn12.source.file(wsapi_env.input),
+ ltn12.sink.file(wsapi_env.error)
+ )
local res, id, data1, data2 = true, 0, nil, nil
local headers = {}
]]--
module("luci.http", package.seeall)
+require("ltn12")
require("luci.http.protocol")
require("luci.util")
Request = luci.util.class()
-function Request.__init__(self, env, instream, errstream)
- self.input = instream
- self.error = errstream
-
- -- 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
+function Request.__init__(self, env, sourcein, sinkerr)
+ self.input = sourcein
+ self.error = sinkerr
+
-- File handler
self.filehandler = function() end
self.message = {
env = env,
headers = {},
- params = luci.http.protocol.urldecode_params("?"..(env.QUERY_STRING or "")),
+ params = luci.http.protocol.urldecode_params(env.QUERY_STRING or ""),
}
setmetatable(self.message.params, {__index =
function(tbl, key)
luci.http.protocol.parse_message_body(
- self.inputreader,
+ self.input,
self.message,
self.filehandler
)