summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2008-06-20 19:57:57 +0000
committerSteven Barth <steven@midlink.org>2008-06-20 19:57:57 +0000
commit65870edf9f1e579b4301e1677d70c9387a9a72dc (patch)
treead34a187c824027f8e328bece03c3f67527a89f2
parente2e9e119d670ec80954fc8c018b479b218a7e47e (diff)
* libs/core: Added garbage collector to luci.util.threadlocal to avoid memory leaks
* 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
-rw-r--r--libs/core/luasrc/util.lua7
-rw-r--r--libs/http/luasrc/http/protocol.lua19
-rw-r--r--libs/sgi-cgi/luasrc/sgi/cgi.lua7
-rw-r--r--libs/sgi-webuci/luasrc/sgi/webuci.lua8
-rw-r--r--libs/sgi-wsapi/luasrc/sgi/wsapi.lua9
-rw-r--r--libs/web/luasrc/http.lua18
6 files changed, 45 insertions, 23 deletions
diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua
index 3a0b2fbfc..516856057 100644
--- a/libs/core/luasrc/util.lua
+++ b/libs/core/luasrc/util.lua
@@ -281,6 +281,13 @@ function threadlocal()
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})
diff --git a/libs/http/luasrc/http/protocol.lua b/libs/http/luasrc/http/protocol.lua
index 01d3128b2..6e53d7ca1 100644
--- a/libs/http/luasrc/http/protocol.lua
+++ b/libs/http/luasrc/http/protocol.lua
@@ -378,8 +378,8 @@ process_states['urldecode-init'] = function( msg, chunk, filecb )
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
@@ -404,7 +404,6 @@ end
-- Process urldecoding stream, read and validate parameter key
process_states['urldecode-key'] = function( msg, chunk, filecb )
-
if chunk ~= nil then
-- Prevent oversized requests
@@ -436,6 +435,11 @@ process_states['urldecode-key'] = function( msg, chunk, filecb )
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
@@ -520,9 +524,9 @@ 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
@@ -666,7 +670,8 @@ function parse_message_header( source )
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
@@ -707,8 +712,8 @@ function parse_message_body( source, msg, filecb )
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
diff --git a/libs/sgi-cgi/luasrc/sgi/cgi.lua b/libs/sgi-cgi/luasrc/sgi/cgi.lua
index 7abb1ef78..8ba4c54a3 100644
--- a/libs/sgi-cgi/luasrc/sgi/cgi.lua
+++ b/libs/sgi-cgi/luasrc/sgi/cgi.lua
@@ -24,12 +24,17 @@ limitations under the License.
]]--
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)
diff --git a/libs/sgi-webuci/luasrc/sgi/webuci.lua b/libs/sgi-webuci/luasrc/sgi/webuci.lua
index 7bfa2fe13..cf8cbcce2 100644
--- a/libs/sgi-webuci/luasrc/sgi/webuci.lua
+++ b/libs/sgi-webuci/luasrc/sgi/webuci.lua
@@ -24,12 +24,18 @@ limitations under the License.
]]--
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)
diff --git a/libs/sgi-wsapi/luasrc/sgi/wsapi.lua b/libs/sgi-wsapi/luasrc/sgi/wsapi.lua
index f77ac5c5b..5b237cd7a 100644
--- a/libs/sgi-wsapi/luasrc/sgi/wsapi.lua
+++ b/libs/sgi-wsapi/luasrc/sgi/wsapi.lua
@@ -24,14 +24,17 @@ limitations under the License.
]]--
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 = {}
diff --git a/libs/web/luasrc/http.lua b/libs/web/luasrc/http.lua
index f2c366073..2bd914429 100644
--- a/libs/web/luasrc/http.lua
+++ b/libs/web/luasrc/http.lua
@@ -28,6 +28,7 @@ limitations under the License.
]]--
module("luci.http", package.seeall)
+require("ltn12")
require("luci.http.protocol")
require("luci.util")
@@ -35,15 +36,10 @@ context = luci.util.threadlocal()
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
@@ -52,13 +48,13 @@ function Request.__init__(self, env, instream, errstream)
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
)