luci-base: log login attempts
[project/luci.git] / modules / luci-base / luasrc / http / protocol.lua
index 61d7b80..0a8b2fb 100644 (file)
@@ -72,7 +72,7 @@ function urlencode( str )
 
        if type(str) == "string" then
                str = str:gsub(
-                       "([^a-zA-Z0-9$_%-%.!*'(),])",
+                       "([^a-zA-Z0-9$_%-%.%~])",
                        __chrenc
                )
        end
@@ -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 )
@@ -254,7 +264,7 @@ function header_source( sock )
 end
 
 -- Content-Type. Stores all extracted data associated with its parameter name
--- in the params table withing the given message object. Multiple parameter
+-- in the params table within the given message object. Multiple parameter
 -- values are stored as tables, ordinary ones as strings.
 -- If an optional file callback function is given then it is feeded with the
 -- file contents chunk by chunk and only the extracted file name is stored
@@ -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 )
 
@@ -407,7 +433,7 @@ function mimedecode_message_body( src, msg, filecb )
 end
 
 -- Content-Type. Stores all extracted data associated with its parameter name
--- in the params table withing the given message object. Multiple parameter
+-- in the params table within the given message object. Multiple parameter
 -- values are stored as tables, ordinary ones as strings.
 function urldecode_message_body( src, msg )
 
@@ -559,14 +585,23 @@ function parse_message_body( src, msg, filecb )
 
                -- If we have a file callback then feed it
                if type(filecb) == "function" then
-                       sink = filecb
-
+                       local meta = {
+                               name = "raw",
+                               encoding = msg.env.CONTENT_TYPE
+                       }
+                       sink = function( chunk )
+                               if chunk then
+                                       return filecb(meta, chunk, false)
+                               else
+                                       return filecb(meta, nil, true)
+                               end
+                       end
                -- ... else append to .content
                else
                        msg.content = ""
                        msg.content_length = 0
 
-                       sink = function( chunk, err )
+                       sink = function( chunk )
                                if chunk then
                                        if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then
                                                msg.content        = msg.content        .. chunk