X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=libs%2Fhttp%2Fluasrc%2Fhttp%2Fprotocol.lua;h=542c3147ea3f49570264e4e1d18cc36bf6af1157;hp=205869a2d8a4f6942c7525155b3e193b7cbe3d21;hb=8d1aff78b17d6f7437d776bdf53a6aa2112f31db;hpb=7a4aa85dd64f72b9edcbf9310d0d95e59960d84e diff --git a/libs/http/luasrc/http/protocol.lua b/libs/http/luasrc/http/protocol.lua index 205869a2d..542c3147e 100644 --- a/libs/http/luasrc/http/protocol.lua +++ b/libs/http/luasrc/http/protocol.lua @@ -15,23 +15,27 @@ $Id$ module("luci.http.protocol", package.seeall) -require("ltn12") -require("luci.http.protocol.filter") +local ltn12 = require("luci.ltn12") HTTP_MAX_CONTENT = 1024*4 -- 4 kB maximum content size HTTP_URLENC_MAXKEYLEN = 1024 -- maximum allowd size of urlencoded parameter names +TSRC_BLOCKSIZE = 2048 -- target block size for throttling sources -- Decode an urlencoded string. -- Returns the decoded value. -function urldecode( str ) +function urldecode( str, no_plus ) local function __chrdec( hex ) return string.char( tonumber( hex, 16 ) ) end if type(str) == "string" then - str = str:gsub( "+", " " ):gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec ) + if not no_plus then + str = str:gsub( "+", " " ) + end + + str = str:gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec ) end return str @@ -84,7 +88,7 @@ function urlencode( str ) if type(str) == "string" then str = str:gsub( - "([^a-zA-Z0-9$_%-%.+!*'(),])", + "([^a-zA-Z0-9$_%-%.%+!*'(),])", __chrenc ) end @@ -108,6 +112,36 @@ function urlencode_params( tbl ) end +-- Parameter helper +local function __initval( tbl, key ) + if tbl[key] == nil then + tbl[key] = "" + elseif type(tbl[key]) == "string" then + tbl[key] = { tbl[key], "" } + else + table.insert( tbl[key], "" ) + end +end + +local function __appendval( tbl, key, chunk ) + if type(tbl[key]) == "table" then + tbl[key][#tbl[key]] = tbl[key][#tbl[key]] .. chunk + else + tbl[key] = tbl[key] .. chunk + end +end + +local function __finishval( tbl, key, handler ) + if handler then + if type(tbl[key]) == "table" then + tbl[key][#tbl[key]] = handler( tbl[key][#tbl[key]] ) + else + tbl[key] = handler( tbl[key] ) + end + end +end + + -- Table of our process states local process_states = { } @@ -160,7 +194,7 @@ process_states['magic'] = function( msg, chunk, err ) end end end - + -- Can't handle it return nil, "Invalid HTTP message magic" end @@ -282,9 +316,10 @@ process_states['mime-headers'] = function( msg, chunk, filecb ) -- Treat as form field else - msg.params[field] = "" + __initval( msg.params, field ) + msg._mimecallback = function(chunk,eof) - msg.params[field] = msg.params[field] .. chunk + __appendval( msg.params, field, chunk ) end end @@ -427,7 +462,6 @@ process_states['urldecode-key'] = function( msg, chunk, filecb ) local key = urldecode( buffer:sub( 1, spos - 1 ) ) -- Prepare buffers - msg.params[key] = "" msg._urldeclength = msg._urldeclength + epos msg._urldecbuffer = buffer:sub( epos + 1, #buffer ) @@ -437,12 +471,14 @@ process_states['urldecode-key'] = function( msg, chunk, filecb ) filecb( field, chunk, eof ) end else + __initval( msg.params, key ) + msg._urldeccallback = function( chunk, eof ) - msg.params[key] = msg.params[key] .. chunk + __appendval( msg.params, key, chunk ) -- FIXME: Use a filter if eof then - msg.params[key] = urldecode( msg.params[key] ) + __finishval( msg.params, key, urldecode ) end end end @@ -533,10 +569,10 @@ function header_source( sock ) local chunk, err, part = sock:receive("*l") -- Line too long - if chunk == nil then + if chunk == nil then if err ~= "timeout" then return nil, part - and "Line exceeds maximum allowed length["..part.."]" + and "Line exceeds maximum allowed length" or "Unexpected EOF" else return nil, err @@ -587,7 +623,7 @@ function mimedecode_message_body( source, msg, filecb ) -- XXX: we schould propably keep the maximum buffer size in sync with -- the blocksize of our original source... but doesn't really matter - if msg._mimebuffer ~= null and #msg._mimebuffer > 256 then + if msg._mimebuffer ~= nil and #msg._mimebuffer > TSRC_BLOCKSIZE then return "" else return source() @@ -625,7 +661,7 @@ function urldecode_message_body( source, msg ) -- Create a throttling LTN12 source -- See explaination in mimedecode_message_body(). local tsrc = function() - if msg._urldecbuffer ~= null and #msg._urldecbuffer > 0 then + if msg._urldecbuffer ~= nil and #msg._urldecbuffer > 0 then return "" else return source() @@ -779,11 +815,14 @@ end -- Status codes statusmsg = { [200] = "OK", + [301] = "Moved Permanently", + [304] = "Not Modified", [400] = "Bad Request", [403] = "Forbidden", [404] = "Not Found", [405] = "Method Not Allowed", [411] = "Length Required", + [412] = "Precondition Failed", [500] = "Internal Server Error", [503] = "Server Unavailable", }