summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--libs/luci-lib-nixio/src/file.c33
-rw-r--r--modules/luci-base/luasrc/http.lua31
-rw-r--r--modules/luci-base/luasrc/http/protocol.lua26
3 files changed, 90 insertions, 0 deletions
diff --git a/libs/luci-lib-nixio/src/file.c b/libs/luci-lib-nixio/src/file.c
index b86e040e1d..cfa35dfd17 100644
--- a/libs/luci-lib-nixio/src/file.c
+++ b/libs/luci-lib-nixio/src/file.c
@@ -79,6 +79,38 @@ static int nixio_open(lua_State *L) {
return 1;
}
+static int nixio_mkstemp(lua_State *L) {
+ const char *intemplate = luaL_checklstring(L, 1, NULL);
+ size_t len = lua_strlen(L, 1);
+ char *template = (char *)lua_newuserdata(L, 13 + len);
+ if (!template) {
+ return luaL_error(L, "out of memory");
+ }
+ snprintf(template, 13 + len, "/tmp/%s.XXXXXX", intemplate);
+
+ int fd;
+
+ do {
+ fd = mkstemp(template);
+ } while (fd == -1 && errno == EINTR);
+ if (fd == -1) {
+ return nixio__perror(L);
+ }
+ unlink(template);
+
+ int *udata = lua_newuserdata(L, sizeof(int));
+ if (!udata) {
+ return luaL_error(L, "out of memory");
+ }
+
+ *udata = fd;
+
+ luaL_getmetatable(L, NIXIO_FILE_META);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
static int nixio_open_flags(lua_State *L) {
int mode = 0;
const int j = lua_gettop(L);
@@ -366,6 +398,7 @@ static const luaL_reg R[] = {
{"dup", nixio_dup},
{"open", nixio_open},
{"open_flags", nixio_open_flags},
+ {"mkstemp", nixio_mkstemp},
{"pipe", nixio_pipe},
{NULL, NULL}
};
diff --git a/modules/luci-base/luasrc/http.lua b/modules/luci-base/luasrc/http.lua
index 4b35731727..8795dfc4b2 100644
--- a/modules/luci-base/luasrc/http.lua
+++ b/modules/luci-base/luasrc/http.lua
@@ -89,6 +89,37 @@ end
function Request.setfilehandler(self, callback)
self.filehandler = callback
+
+ -- If input has already been parsed then any files are either in temporary files
+ -- or are in self.message.params[key]
+ if self.parsed_input then
+ for param, value in pairs(self.message.params) do
+ repeat
+ -- We're only interested in files
+ if (not value["file"]) then break end
+ -- If we were able to write to temporary file
+ if (value["fd"]) then
+ fd = value["fd"]
+ local eof = false
+ repeat
+ filedata = fd:read(1024)
+ if (filedata:len() < 1024) then
+ eof = true
+ end
+ callback({ name=value["name"], file=value["file"] }, filedata, eof)
+ until (eof)
+ fd:close()
+ value["fd"] = nil
+ -- We had to read into memory
+ else
+ -- There should only be one numbered value in table - the data
+ for k, v in ipairs(value) do
+ callback({ name=value["name"], file=value["file"] }, v, true)
+ end
+ end
+ until true
+ end
+ end
end
function Request._parse_input(self)
diff --git a/modules/luci-base/luasrc/http/protocol.lua b/modules/luci-base/luasrc/http/protocol.lua
index 0cb62aeec9..061c6ad544 100644
--- a/modules/luci-base/luasrc/http/protocol.lua
+++ b/modules/luci-base/luasrc/http/protocol.lua
@@ -114,6 +114,16 @@ local function __initval( tbl, key )
end
-- (Internal function)
+-- Initialize given file parameter.
+local function __initfileval( tbl, key, filename, fd )
+ if tbl[key] == nil then
+ tbl[key] = { file=filename, fd=fd, name=key, "" }
+ else
+ table.insert( tbl[key], "" )
+ end
+end
+
+-- (Internal function)
-- Append given data to given parameter, either by extending the string value
-- or by appending it to the last string in the parameter's value table.
local function __appendval( tbl, key, chunk )
@@ -313,6 +323,22 @@ function mimedecode_message_body( src, msg, filecb )
__appendval( msg.params, field.name, field.file )
store = filecb
+ elseif field.name and field.file then
+ local nxf = require "nixio"
+ local fd = nxf.mkstemp(field.name)
+ __initfileval ( msg.params, field.name, field.file, fd )
+ if fd then
+ store = function(hdr, buf, eof)
+ fd:write(buf)
+ if (eof) then
+ fd:seek(0, "set")
+ end
+ end
+ else
+ store = function( hdr, buf, eof )
+ __appendval( msg.params, field.name, buf )
+ end
+ end
elseif field.name then
__initval( msg.params, field.name )